aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoretobi <git@e-tobi.net>2013-09-03 09:48:41 +0200
committeretobi <git@e-tobi.net>2013-09-03 09:48:41 +0200
commitab959d7b4194715870128e616b8e29d4a101e488 (patch)
tree61a746231d30817be73416a7d67763fd677a1042
parent6b350466c4902c5b137e0efaf1d189128a7f18f5 (diff)
downloadlinux-dvb-apps-ab959d7b4194715870128e616b8e29d4a101e488.tar.gz
Imported Upstream version 1.1.1+rev1207upstream/1.1.1+rev1207
-rw-r--r--.hg_archival.txt2
-rw-r--r--COPYING339
-rw-r--r--COPYING.LGPL502
-rw-r--r--INSTALL26
-rw-r--r--Make.rules104
-rw-r--r--Makefile32
-rw-r--r--README46
-rw-r--r--TODO1
-rw-r--r--include/audio.h (renamed from include/linux/dvb/audio.h)67
-rw-r--r--include/ca.h (renamed from include/linux/dvb/ca.h)41
-rw-r--r--include/dmx.h (renamed from include/linux/dvb/dmx.h)59
-rw-r--r--include/frontend.h648
-rw-r--r--include/linux/dvb/frontend.h267
-rw-r--r--include/net.h (renamed from include/linux/dvb/net.h)24
-rw-r--r--include/osd.h (renamed from include/linux/dvb/osd.h)55
-rw-r--r--include/version.h (renamed from include/linux/dvb/version.h)2
-rw-r--r--include/video.h (renamed from include/linux/dvb/video.h)174
-rw-r--r--lib/Makefile11
-rw-r--r--lib/libdvbapi/Makefile25
-rw-r--r--lib/libdvbapi/dvbaudio.c50
-rw-r--r--lib/libdvbapi/dvbaudio.h55
-rw-r--r--lib/libdvbapi/dvbca.c159
-rw-r--r--lib/libdvbapi/dvbca.h135
-rw-r--r--lib/libdvbapi/dvbdemux.c255
-rw-r--r--lib/libdvbapi/dvbdemux.h204
-rw-r--r--lib/libdvbapi/dvbfe.c574
-rw-r--r--lib/libdvbapi/dvbfe.h333
-rw-r--r--lib/libdvbapi/dvbnet.c104
-rw-r--r--lib/libdvbapi/dvbnet.h87
-rw-r--r--lib/libdvbapi/dvbvideo.c46
-rw-r--r--lib/libdvbapi/dvbvideo.h46
-rw-r--r--lib/libdvbcfg/Makefile18
-rw-r--r--lib/libdvbcfg/dvbcfg_common.c136
-rw-r--r--lib/libdvbcfg/dvbcfg_common.h37
-rw-r--r--lib/libdvbcfg/dvbcfg_scanfile.c282
-rw-r--r--lib/libdvbcfg/dvbcfg_scanfile.h61
-rw-r--r--lib/libdvbcfg/dvbcfg_zapchannel.c384
-rw-r--r--lib/libdvbcfg/dvbcfg_zapchannel.h77
-rw-r--r--lib/libdvbcfg/zapchannel.txt72
-rw-r--r--lib/libdvben50221/Makefile49
-rw-r--r--lib/libdvben50221/asn_1.c83
-rw-r--r--lib/libdvben50221/asn_1.h41
-rw-r--r--lib/libdvben50221/en50221_app_ai.c191
-rw-r--r--lib/libdvben50221/en50221_app_ai.h136
-rw-r--r--lib/libdvben50221/en50221_app_auth.c180
-rw-r--r--lib/libdvben50221/en50221_app_auth.h123
-rw-r--r--lib/libdvben50221/en50221_app_ca.c631
-rw-r--r--lib/libdvben50221/en50221_app_ca.h264
-rw-r--r--lib/libdvben50221/en50221_app_datetime.c173
-rw-r--r--lib/libdvben50221/en50221_app_datetime.h119
-rw-r--r--lib/libdvben50221/en50221_app_dvb.c282
-rw-r--r--lib/libdvben50221/en50221_app_dvb.h176
-rw-r--r--lib/libdvben50221/en50221_app_epg.c167
-rw-r--r--lib/libdvben50221/en50221_app_epg.h138
-rw-r--r--lib/libdvben50221/en50221_app_lowspeed.c533
-rw-r--r--lib/libdvben50221/en50221_app_lowspeed.h219
-rw-r--r--lib/libdvben50221/en50221_app_mmi.c1397
-rw-r--r--lib/libdvben50221/en50221_app_mmi.h618
-rw-r--r--lib/libdvben50221/en50221_app_rm.c307
-rw-r--r--lib/libdvben50221/en50221_app_rm.h187
-rw-r--r--lib/libdvben50221/en50221_app_smartcard.c296
-rw-r--r--lib/libdvben50221/en50221_app_smartcard.h200
-rw-r--r--lib/libdvben50221/en50221_app_tags.h104
-rw-r--r--lib/libdvben50221/en50221_app_teletext.c141
-rw-r--r--lib/libdvben50221/en50221_app_teletext.h107
-rw-r--r--lib/libdvben50221/en50221_app_utils.c38
-rw-r--r--lib/libdvben50221/en50221_app_utils.h112
-rw-r--r--lib/libdvben50221/en50221_errno.h49
-rw-r--r--lib/libdvben50221/en50221_session.c1055
-rw-r--r--lib/libdvben50221/en50221_session.h232
-rw-r--r--lib/libdvben50221/en50221_stdcam.c54
-rw-r--r--lib/libdvben50221/en50221_stdcam.h102
-rw-r--r--lib/libdvben50221/en50221_stdcam_hlci.c216
-rw-r--r--lib/libdvben50221/en50221_stdcam_llci.c437
-rw-r--r--lib/libdvben50221/en50221_transport.c1296
-rw-r--r--lib/libdvben50221/en50221_transport.h234
-rw-r--r--lib/libdvbmisc/dvbmisc.h72
-rw-r--r--lib/libdvbsec/Makefile17
-rw-r--r--lib/libdvbsec/dvbsec_api.c951
-rw-r--r--lib/libdvbsec/dvbsec_api.h436
-rw-r--r--lib/libdvbsec/dvbsec_cfg.c366
-rw-r--r--lib/libdvbsec/dvbsec_cfg.h203
-rw-r--r--lib/libesg/Makefile27
-rw-r--r--lib/libesg/TODO18
-rw-r--r--lib/libesg/bootstrap/Makefile24
-rw-r--r--lib/libesg/bootstrap/access_descriptor.c115
-rw-r--r--lib/libesg/bootstrap/access_descriptor.h86
-rw-r--r--lib/libesg/bootstrap/provider_discovery_descriptor.c50
-rw-r--r--lib/libesg/bootstrap/provider_discovery_descriptor.h59
-rw-r--r--lib/libesg/encapsulation/Makefile28
-rw-r--r--lib/libesg/encapsulation/auxiliary_data.h62
-rw-r--r--lib/libesg/encapsulation/container.c206
-rw-r--r--lib/libesg/encapsulation/container.h94
-rw-r--r--lib/libesg/encapsulation/data_repository.c53
-rw-r--r--lib/libesg/encapsulation/data_repository.h59
-rw-r--r--lib/libesg/encapsulation/fragment_management_information.c118
-rw-r--r--lib/libesg/encapsulation/fragment_management_information.h96
-rw-r--r--lib/libesg/encapsulation/string_repository.c54
-rw-r--r--lib/libesg/encapsulation/string_repository.h60
-rw-r--r--lib/libesg/representation/Makefile26
-rw-r--r--lib/libesg/representation/bim_decoder_init.h40
-rw-r--r--lib/libesg/representation/encapsulated_bim_esg_xml_fragment.h40
-rw-r--r--lib/libesg/representation/encapsulated_textual_esg_xml_fragment.c70
-rw-r--r--lib/libesg/representation/encapsulated_textual_esg_xml_fragment.h60
-rw-r--r--lib/libesg/representation/init_message.c112
-rw-r--r--lib/libesg/representation/init_message.h80
-rw-r--r--lib/libesg/representation/textual_decoder_init.c128
-rw-r--r--lib/libesg/representation/textual_decoder_init.h104
-rw-r--r--lib/libesg/transport/Makefile22
-rw-r--r--lib/libesg/transport/session_partition_declaration.c253
-rw-r--r--lib/libesg/transport/session_partition_declaration.h139
-rw-r--r--lib/libesg/types.c37
-rw-r--r--lib/libesg/types.h53
-rw-r--r--lib/libesg/xml/provider_discovery_descriptor.xsd22
-rw-r--r--lib/libucsi/Makefile34
-rw-r--r--lib/libucsi/atsc/Makefile55
-rw-r--r--lib/libucsi/atsc/ac3_descriptor.h112
-rw-r--r--lib/libucsi/atsc/atsc_text.c743
-rw-r--r--lib/libucsi/atsc/caption_service_descriptor.h137
-rw-r--r--lib/libucsi/atsc/component_name_descriptor.h92
-rw-r--r--lib/libucsi/atsc/content_advisory_descriptor.h235
-rw-r--r--lib/libucsi/atsc/cvct_section.c77
-rw-r--r--lib/libucsi/atsc/cvct_section.h228
-rw-r--r--lib/libucsi/atsc/dcc_arriving_request_descriptor.h107
-rw-r--r--lib/libucsi/atsc/dcc_departing_request_descriptor.h108
-rw-r--r--lib/libucsi/atsc/dccsct_section.c109
-rw-r--r--lib/libucsi/atsc/dccsct_section.h327
-rw-r--r--lib/libucsi/atsc/dcct_section.c96
-rw-r--r--lib/libucsi/atsc/dcct_section.h380
-rw-r--r--lib/libucsi/atsc/descriptor.h68
-rw-r--r--lib/libucsi/atsc/eit_section.c71
-rw-r--r--lib/libucsi/atsc/eit_section.h191
-rw-r--r--lib/libucsi/atsc/ett_section.c42
-rw-r--r--lib/libucsi/atsc/ett_section.h91
-rw-r--r--lib/libucsi/atsc/extended_channel_name_descriptor.h92
-rw-r--r--lib/libucsi/atsc/genre_descriptor.h82
-rw-r--r--lib/libucsi/atsc/mgt_section.c76
-rw-r--r--lib/libucsi/atsc/mgt_section.h215
-rw-r--r--lib/libucsi/atsc/rc_descriptor.h83
-rw-r--r--lib/libucsi/atsc/rrt_section.c108
-rw-r--r--lib/libucsi/atsc/rrt_section.h379
-rw-r--r--lib/libucsi/atsc/section.h84
-rw-r--r--lib/libucsi/atsc/service_location_descriptor.h141
-rw-r--r--lib/libucsi/atsc/stt_section.c42
-rw-r--r--lib/libucsi/atsc/stt_section.h105
-rw-r--r--lib/libucsi/atsc/stuffing_descriptor.h82
-rw-r--r--lib/libucsi/atsc/time_shifted_service_descriptor.h136
-rw-r--r--lib/libucsi/atsc/tvct_section.c81
-rw-r--r--lib/libucsi/atsc/tvct_section.h227
-rw-r--r--lib/libucsi/atsc/types.c71
-rw-r--r--lib/libucsi/atsc/types.h227
-rw-r--r--lib/libucsi/crc32.c89
-rw-r--r--lib/libucsi/crc32.h58
-rw-r--r--lib/libucsi/descriptor.h129
-rw-r--r--lib/libucsi/dvb/Makefile121
-rw-r--r--lib/libucsi/dvb/ac3_descriptor.h88
-rw-r--r--lib/libucsi/dvb/adaptation_field_data_descriptor.h62
-rw-r--r--lib/libucsi/dvb/ait_application_descriptor.h204
-rw-r--r--lib/libucsi/dvb/ait_application_icons_descriptor.h157
-rw-r--r--lib/libucsi/dvb/ait_application_name_descriptor.h145
-rw-r--r--lib/libucsi/dvb/ait_external_application_authorisation_descriptor.h125
-rw-r--r--lib/libucsi/dvb/ancillary_data_descriptor.h67
-rw-r--r--lib/libucsi/dvb/announcement_support_descriptor.h219
-rw-r--r--lib/libucsi/dvb/application_signalling_descriptor.h124
-rw-r--r--lib/libucsi/dvb/bat_section.c77
-rw-r--r--lib/libucsi/dvb/bat_section.h211
-rw-r--r--lib/libucsi/dvb/bouquet_name_descriptor.h82
-rw-r--r--lib/libucsi/dvb/ca_identifier_descriptor.h94
-rw-r--r--lib/libucsi/dvb/cable_delivery_descriptor.h70
-rw-r--r--lib/libucsi/dvb/cell_frequency_link_descriptor.h190
-rw-r--r--lib/libucsi/dvb/cell_list_descriptor.h201
-rw-r--r--lib/libucsi/dvb/component_descriptor.h147
-rw-r--r--lib/libucsi/dvb/content_descriptor.h116
-rw-r--r--lib/libucsi/dvb/content_identifier_descriptor.h233
-rw-r--r--lib/libucsi/dvb/country_availability_descriptor.h120
-rw-r--r--lib/libucsi/dvb/data_broadcast_descriptor.h139
-rw-r--r--lib/libucsi/dvb/data_broadcast_id_descriptor.h221
-rw-r--r--lib/libucsi/dvb/default_authority_descriptor.h82
-rw-r--r--lib/libucsi/dvb/descriptor.h229
-rw-r--r--lib/libucsi/dvb/dit_section.c32
-rw-r--r--lib/libucsi/dvb/dit_section.h54
-rw-r--r--lib/libucsi/dvb/dsng_descriptor.h80
-rw-r--r--lib/libucsi/dvb/eit_section.c63
-rw-r--r--lib/libucsi/dvb/eit_section.h160
-rw-r--r--lib/libucsi/dvb/extended_event_descriptor.h232
-rw-r--r--lib/libucsi/dvb/frequency_list_descriptor.h107
-rw-r--r--lib/libucsi/dvb/int_section.c79
-rw-r--r--lib/libucsi/dvb/int_section.h245
-rw-r--r--lib/libucsi/dvb/ip_mac_platform_name_descriptor.h87
-rw-r--r--lib/libucsi/dvb/ip_mac_platform_provider_name_descriptor.h87
-rw-r--r--lib/libucsi/dvb/ip_mac_stream_location_descriptor.h73
-rw-r--r--lib/libucsi/dvb/linkage_descriptor.h480
-rw-r--r--lib/libucsi/dvb/local_time_offset_descriptor.h127
-rw-r--r--lib/libucsi/dvb/mhp_data_broadcast_id_descriptor.h110
-rw-r--r--lib/libucsi/dvb/mosaic_descriptor.h324
-rw-r--r--lib/libucsi/dvb/multilingual_bouquet_name_descriptor.h145
-rw-r--r--lib/libucsi/dvb/multilingual_component_descriptor.h149
-rw-r--r--lib/libucsi/dvb/multilingual_network_name_descriptor.h145
-rw-r--r--lib/libucsi/dvb/multilingual_service_name_descriptor.h197
-rw-r--r--lib/libucsi/dvb/network_name_descriptor.h82
-rw-r--r--lib/libucsi/dvb/nit_section.c78
-rw-r--r--lib/libucsi/dvb/nit_section.h207
-rw-r--r--lib/libucsi/dvb/nvod_reference_descriptor.h125
-rw-r--r--lib/libucsi/dvb/parental_rating_descriptor.h135
-rw-r--r--lib/libucsi/dvb/partial_transport_stream_descriptor.h68
-rw-r--r--lib/libucsi/dvb/pdc_descriptor.h64
-rw-r--r--lib/libucsi/dvb/private_data_specifier_descriptor.h63
-rw-r--r--lib/libucsi/dvb/related_content_descriptor.h56
-rw-r--r--lib/libucsi/dvb/rnt_rar_over_dvb_stream_descriptor.h110
-rw-r--r--lib/libucsi/dvb/rnt_rar_over_ip_descriptor.h87
-rw-r--r--lib/libucsi/dvb/rnt_rnt_scan_descriptor.h125
-rw-r--r--lib/libucsi/dvb/rst_section.c47
-rw-r--r--lib/libucsi/dvb/rst_section.h110
-rw-r--r--lib/libucsi/dvb/s2_satellite_delivery_descriptor.h116
-rw-r--r--lib/libucsi/dvb/satellite_delivery_descriptor.h73
-rw-r--r--lib/libucsi/dvb/scrambling_descriptor.h61
-rw-r--r--lib/libucsi/dvb/sdt_section.c60
-rw-r--r--lib/libucsi/dvb/sdt_section.h157
-rw-r--r--lib/libucsi/dvb/section.h107
-rw-r--r--lib/libucsi/dvb/service_availability_descriptor.h98
-rw-r--r--lib/libucsi/dvb/service_descriptor.h163
-rw-r--r--lib/libucsi/dvb/service_identifier_descriptor.h82
-rw-r--r--lib/libucsi/dvb/service_list_descriptor.h122
-rw-r--r--lib/libucsi/dvb/service_move_descriptor.h67
-rw-r--r--lib/libucsi/dvb/short_event_descriptor.h135
-rw-r--r--lib/libucsi/dvb/short_smoothing_buffer_descriptor.h87
-rw-r--r--lib/libucsi/dvb/sit_section.c69
-rw-r--r--lib/libucsi/dvb/sit_section.h173
-rw-r--r--lib/libucsi/dvb/st_section.c29
-rw-r--r--lib/libucsi/dvb/st_section.h77
-rw-r--r--lib/libucsi/dvb/stream_identifier_descriptor.h61
-rw-r--r--lib/libucsi/dvb/stuffing_descriptor.h82
-rw-r--r--lib/libucsi/dvb/subtitling_descriptor.h126
-rw-r--r--lib/libucsi/dvb/target_ip_address_descriptor.h116
-rw-r--r--lib/libucsi/dvb/target_ip_slash_descriptor.h116
-rw-r--r--lib/libucsi/dvb/target_ip_source_slash_descriptor.h118
-rw-r--r--lib/libucsi/dvb/target_ipv6_address_descriptor.h116
-rw-r--r--lib/libucsi/dvb/target_ipv6_slash_descriptor.h116
-rw-r--r--lib/libucsi/dvb/target_ipv6_source_slash_descriptor.h118
-rw-r--r--lib/libucsi/dvb/tdt_section.c33
-rw-r--r--lib/libucsi/dvb/tdt_section.h54
-rw-r--r--lib/libucsi/dvb/telephone_descriptor.h150
-rw-r--r--lib/libucsi/dvb/teletext_descriptor.h127
-rw-r--r--lib/libucsi/dvb/terrestrial_delivery_descriptor.h77
-rw-r--r--lib/libucsi/dvb/time_shifted_event_descriptor.h65
-rw-r--r--lib/libucsi/dvb/time_shifted_service_descriptor.h63
-rw-r--r--lib/libucsi/dvb/tot_section.c50
-rw-r--r--lib/libucsi/dvb/tot_section.h97
-rw-r--r--lib/libucsi/dvb/transport_stream_descriptor.h82
-rw-r--r--lib/libucsi/dvb/tva_container_section.c33
-rw-r--r--lib/libucsi/dvb/tva_container_section.h90
-rw-r--r--lib/libucsi/dvb/tva_id_descriptor.h124
-rw-r--r--lib/libucsi/dvb/types.c270
-rw-r--r--lib/libucsi/dvb/types.h127
-rw-r--r--lib/libucsi/dvb/vbi_data_descriptor.h186
-rw-r--r--lib/libucsi/dvb/vbi_teletext_descriptor.h116
-rw-r--r--lib/libucsi/endianops.h128
-rw-r--r--lib/libucsi/mpeg/Makefile65
-rw-r--r--lib/libucsi/mpeg/audio_stream_descriptor.h65
-rw-r--r--lib/libucsi/mpeg/ca_descriptor.h91
-rw-r--r--lib/libucsi/mpeg/cat_section.c34
-rw-r--r--lib/libucsi/mpeg/cat_section.h94
-rw-r--r--lib/libucsi/mpeg/content_labelling_descriptor.h356
-rw-r--r--lib/libucsi/mpeg/copyright_descriptor.h89
-rw-r--r--lib/libucsi/mpeg/data_stream_alignment_descriptor.h73
-rw-r--r--lib/libucsi/mpeg/descriptor.h102
-rw-r--r--lib/libucsi/mpeg/external_es_id_descriptor.h63
-rw-r--r--lib/libucsi/mpeg/fmc_descriptor.h122
-rw-r--r--lib/libucsi/mpeg/fmxbuffer_size_descriptor.h83
-rw-r--r--lib/libucsi/mpeg/hierarchy_descriptor.h83
-rw-r--r--lib/libucsi/mpeg/ibp_descriptor.h65
-rw-r--r--lib/libucsi/mpeg/iod_descriptor.h87
-rw-r--r--lib/libucsi/mpeg/iso_639_language_descriptor.h124
-rw-r--r--lib/libucsi/mpeg/maximum_bitrate_descriptor.h64
-rw-r--r--lib/libucsi/mpeg/metadata_descriptor.h472
-rw-r--r--lib/libucsi/mpeg/metadata_pointer_descriptor.h360
-rw-r--r--lib/libucsi/mpeg/metadata_section.c27
-rw-r--r--lib/libucsi/mpeg/metadata_section.h122
-rw-r--r--lib/libucsi/mpeg/metadata_std_descriptor.h72
-rw-r--r--lib/libucsi/mpeg/mpeg4_audio_descriptor.h61
-rw-r--r--lib/libucsi/mpeg/mpeg4_video_descriptor.h61
-rw-r--r--lib/libucsi/mpeg/multiplex_buffer_descriptor.h65
-rw-r--r--lib/libucsi/mpeg/multiplex_buffer_utilization_descriptor.h67
-rw-r--r--lib/libucsi/mpeg/muxcode_descriptor.h82
-rw-r--r--lib/libucsi/mpeg/odsmt_section.c80
-rw-r--r--lib/libucsi/mpeg/odsmt_section.h224
-rw-r--r--lib/libucsi/mpeg/pat_section.c46
-rw-r--r--lib/libucsi/mpeg/pat_section.h118
-rw-r--r--lib/libucsi/mpeg/pmt_section.c71
-rw-r--r--lib/libucsi/mpeg/pmt_section.h188
-rw-r--r--lib/libucsi/mpeg/private_data_indicator_descriptor.h63
-rw-r--r--lib/libucsi/mpeg/registration_descriptor.h91
-rw-r--r--lib/libucsi/mpeg/section.h58
-rw-r--r--lib/libucsi/mpeg/sl_descriptor.h63
-rw-r--r--lib/libucsi/mpeg/smoothing_buffer_descriptor.h66
-rw-r--r--lib/libucsi/mpeg/std_descriptor.h62
-rw-r--r--lib/libucsi/mpeg/system_clock_descriptor.h65
-rw-r--r--lib/libucsi/mpeg/target_background_grid_descriptor.h66
-rw-r--r--lib/libucsi/mpeg/tsdt_section.c34
-rw-r--r--lib/libucsi/mpeg/tsdt_section.h94
-rw-r--r--lib/libucsi/mpeg/types.h127
-rw-r--r--lib/libucsi/mpeg/video_stream_descriptor.h101
-rw-r--r--lib/libucsi/mpeg/video_window_descriptor.h64
-rw-r--r--lib/libucsi/section.h253
-rw-r--r--lib/libucsi/section_buf.c173
-rw-r--r--lib/libucsi/section_buf.h124
-rw-r--r--lib/libucsi/testrecord.txt146
-rw-r--r--lib/libucsi/transport_packet.c256
-rw-r--r--lib/libucsi/transport_packet.h195
-rw-r--r--lib/libucsi/types.h36
-rw-r--r--libdvb2/README23
-rw-r--r--test/Makefile64
-rw-r--r--test/README11
-rw-r--r--[-rwxr-xr-x]test/dia2
-rw-r--r--test/diseqc.c19
-rw-r--r--test/evtest.c251
-rw-r--r--test/hex_dump.c1
-rw-r--r--test/libdvbcfg/Makefile12
-rw-r--r--test/libdvbcfg/dvbcfg_test.c100
-rw-r--r--test/libdvbcfg/test_zapchannels.txt446
-rw-r--r--test/libdvben50221/Makefile14
-rw-r--r--test/libdvben50221/test-app.c854
-rw-r--r--test/libdvben50221/test-session.c171
-rw-r--r--test/libdvben50221/test-transport.c144
-rw-r--r--test/libdvbsec/Makefile12
-rw-r--r--test/libdvbsec/dvbsec_test.c85
-rw-r--r--test/libdvbsec/test_sec.txt28
-rw-r--r--test/libesg/Makefile12
-rw-r--r--test/libesg/samples/ESGProviderDiscoveryDescriptor.xml13
-rw-r--r--test/libesg/testesg.c563
-rw-r--r--test/libucsi/Makefile13
-rw-r--r--test/libucsi/testucsi.c3528
-rw-r--r--test/lnb.c (renamed from util/lib/lnb.c)6
-rw-r--r--test/lnb.h (renamed from util/lib/lnb.h)2
-rw-r--r--test/sendburst.c14
-rw-r--r--test/set22k.c18
-rw-r--r--test/setpid.c17
-rw-r--r--test/setvoltage.c18
-rw-r--r--test/szap2.c767
-rw-r--r--test/test.c81
-rw-r--r--test/test_audio.c41
-rw-r--r--test/test_av.c100
-rw-r--r--test/test_av_play.c526
-rw-r--r--test/test_dvr.c3
-rw-r--r--test/test_dvr_play.c1
-rw-r--r--test/test_front.c37
-rw-r--r--test/test_sec_ne.c7
-rw-r--r--test/test_sections.c3
-rw-r--r--test/test_stc.c1
-rw-r--r--test/test_stillimage.c7
-rw-r--r--test/test_switch.c106
-rw-r--r--test/test_tt.c1
-rw-r--r--test/test_vevent.c6
-rw-r--r--test/test_video.c51
-rw-r--r--test/video.c42
-rw-r--r--util/Makefile24
-rw-r--r--util/av7110_loadkeys/Makefile69
-rw-r--r--util/av7110_loadkeys/README15
-rw-r--r--util/av7110_loadkeys/activy.rcmm1
-rw-r--r--util/av7110_loadkeys/av7110_loadkeys.c48
-rw-r--r--util/av7110_loadkeys/evtest.c177
-rw-r--r--util/av7110_loadkeys/galaxis.rcmm3
-rw-r--r--util/av7110_loadkeys/generate-keynames.sh37
-rw-r--r--util/av7110_loadkeys/hauppauge.rc51
-rw-r--r--util/av7110_loadkeys/hauppauge2.rc540
-rw-r--r--util/av7110_loadkeys/hauppauge_grey.rc51
-rw-r--r--util/av7110_loadkeys/input_fake.h15
-rw-r--r--util/av7110_loadkeys/philips1358.rc56
-rw-r--r--util/dib3000-watch/Makefile13
-rw-r--r--util/dib3000-watch/README.dib3000-watch29
-rw-r--r--util/dib3000-watch/dib-i2c.h43
-rw-r--r--util/dib3000-watch/dib3000-watch.c296
-rw-r--r--util/dib3000-watch/dib3000-watch.h46
-rw-r--r--util/dib3000-watch/dib3000.h56
-rw-r--r--util/dib3000-watch/make-i2c-dev6
-rw-r--r--util/dst-utils/Makefile13
-rw-r--r--util/dst-utils/dst_test.c258
-rw-r--r--util/dvbdate/Makefile28
-rw-r--r--util/dvbdate/dvbdate.c288
-rw-r--r--util/dvbnet/Makefile32
-rw-r--r--util/dvbnet/dvbnet.c106
-rw-r--r--[-rwxr-xr-x]util/dvbnet/net_start.pl1
-rw-r--r--[-rwxr-xr-x]util/dvbnet/net_start.sh0
-rw-r--r--util/dvbnet/version.h.in1
-rw-r--r--util/dvbscan/Makefile22
-rw-r--r--util/dvbscan/dvbscan.c370
-rw-r--r--util/dvbscan/dvbscan.h136
-rw-r--r--util/dvbscan/dvbscan_atsc.c30
-rw-r--r--util/dvbscan/dvbscan_dvb.c30
-rw-r--r--util/dvbscan/dvbscan_structutils.c99
-rw-r--r--util/dvbtraffic/Makefile17
-rw-r--r--util/dvbtraffic/dvbtraffic.c110
-rw-r--r--util/femon/Makefile15
-rw-r--r--util/femon/femon.c175
-rw-r--r--util/gnutv/Makefile21
-rw-r--r--util/gnutv/gnutv.c365
-rw-r--r--util/gnutv/gnutv.h37
-rw-r--r--util/gnutv/gnutv_ca.c404
-rw-r--r--util/gnutv/gnutv_ca.h40
-rw-r--r--util/gnutv/gnutv_data.c459
-rw-r--r--util/gnutv/gnutv_data.h39
-rw-r--r--util/gnutv/gnutv_dvb.c376
-rw-r--r--util/gnutv/gnutv_dvb.h44
-rw-r--r--util/lib/Makefile20
-rw-r--r--util/scan/Makefile46
-rw-r--r--util/scan/README26
-rw-r--r--util/scan/atsc/us-ATSC-center-frequencies-8VSB1
-rw-r--r--util/scan/atsc/us-NTSC-center-frequencies-8VSB1
-rw-r--r--util/scan/atsc/us-NY-TWC-NYC106
-rw-r--r--util/scan/atsc_psip_section.c62
-rw-r--r--util/scan/atsc_psip_section.h60
-rw-r--r--util/scan/atsc_psip_section.pl76
-rw-r--r--util/scan/diseqc.c5
-rw-r--r--util/scan/diseqc.h1
-rw-r--r--util/scan/dump-vdr.c13
-rw-r--r--util/scan/dump-vdr.h1
-rw-r--r--util/scan/dump-zap.c1
-rw-r--r--util/scan/dump-zap.h1
-rw-r--r--util/scan/dvb-c/at-Innsbruck8
-rw-r--r--util/scan/dvb-c/at-Liwest31
-rw-r--r--util/scan/dvb-c/at-SalzburgAG9
-rw-r--r--util/scan/dvb-c/be-IN.DI-Integan16
-rw-r--r--util/scan/dvb-c/ch-Video20005
-rw-r--r--util/scan/dvb-c/ch-Zuerich-cablecom3
-rw-r--r--util/scan/dvb-c/de-Berlin1
-rw-r--r--util/scan/dvb-c/de-Kabel_BW16
-rw-r--r--util/scan/dvb-c/de-Muenchen24
-rw-r--r--util/scan/dvb-c/de-Primacom29
-rw-r--r--util/scan/dvb-c/de-Unitymedia35
-rw-r--r--util/scan/dvb-c/de-iesy19
-rw-r--r--util/scan/dvb-c/de-neftv23
-rw-r--r--util/scan/dvb-c/dk-Odense10
-rw-r--r--util/scan/dvb-c/es-Euskaltel19
-rw-r--r--util/scan/dvb-c/fi-3ktv23
-rw-r--r--util/scan/dvb-c/fi-HTV4
-rw-r--r--util/scan/dvb-c/fi-Joensuu-Tikka13
-rw-r--r--util/scan/dvb-c/fi-TTV4
-rw-r--r--util/scan/dvb-c/fi-Turku17
-rw-r--r--util/scan/dvb-c/fi-jkl10
-rw-r--r--util/scan/dvb-c/fi-sonera12
-rw-r--r--util/scan/dvb-c/fr-noos-numericable41
-rw-r--r--util/scan/dvb-c/lu-Ettelbruck-ACE20
-rw-r--r--util/scan/dvb-c/nl-Casema3
-rw-r--r--util/scan/dvb-c/no-Oslo-CanalDigital13
-rw-r--r--util/scan/dvb-c/se-comhem3
-rw-r--r--util/scan/dvb-h/README3
-rw-r--r--util/scan/dvb-h/fi-Helsinki2
-rw-r--r--util/scan/dvb-h/fi-Oulu2
-rw-r--r--util/scan/dvb-h/fi-Oulu-Nokia-devel4
-rw-r--r--util/scan/dvb-h/fi-Turku2
-rw-r--r--util/scan/dvb-s/ABS1-75.0E10
-rw-r--r--util/scan/dvb-s/AMC1-103w5
-rw-r--r--util/scan/dvb-s/AMC2-85w6
-rw-r--r--util/scan/dvb-s/AMC3-87w10
-rw-r--r--util/scan/dvb-s/AMC4-101w10
-rw-r--r--util/scan/dvb-s/AMC5-79w5
-rw-r--r--util/scan/dvb-s/AMC6-72w44
-rw-r--r--util/scan/dvb-s/AMC9-83w18
-rw-r--r--util/scan/dvb-s/Amazonas-61.0W54
-rw-r--r--util/scan/dvb-s/Amos-4w70
-rw-r--r--util/scan/dvb-s/Anik-F1-107.3W7
-rw-r--r--util/scan/dvb-s/AsiaSat3S_C-105.5E122
-rw-r--r--util/scan/dvb-s/Astra-28.2E186
-rw-r--r--util/scan/dvb-s/Atlantic-Bird-1-12.5W20
-rw-r--r--util/scan/dvb-s/BrasilSat-B1-75.0W11
-rw-r--r--util/scan/dvb-s/BrasilSat-B2-65.0W34
-rw-r--r--util/scan/dvb-s/BrasilSat-B3-84.0W85
-rw-r--r--util/scan/dvb-s/BrasilSat-B4-70.0W39
-rw-r--r--util/scan/dvb-s/Estrela-do-Sul-63.0W27
-rw-r--r--util/scan/dvb-s/Eurobird1-28.5E5
-rw-r--r--util/scan/dvb-s/EutelsatW2-16E59
-rw-r--r--util/scan/dvb-s/Express-3A-11.0W4
-rw-r--r--util/scan/dvb-s/ExpressAM1-40.0E5
-rw-r--r--util/scan/dvb-s/ExpressAM2-80.0E35
-rw-r--r--util/scan/dvb-s/ExpressAM22-53.0E9
-rw-r--r--util/scan/dvb-s/Galaxy10R-123w10
-rw-r--r--util/scan/dvb-s/Galaxy11-91w49
-rw-r--r--util/scan/dvb-s/Galaxy25-97w19
-rw-r--r--util/scan/dvb-s/Galaxy26-93w58
-rw-r--r--util/scan/dvb-s/Galaxy27-129w4
-rw-r--r--util/scan/dvb-s/Galaxy28-89w41
-rw-r--r--util/scan/dvb-s/Galaxy3C-95w4
-rw-r--r--util/scan/dvb-s/Hispasat-30.0W37
-rw-r--r--util/scan/dvb-s/Hotbird-13.0E93
-rw-r--r--util/scan/dvb-s/IA5-97w18
-rw-r--r--util/scan/dvb-s/IA6-93w61
-rw-r--r--util/scan/dvb-s/IA7-129w4
-rw-r--r--util/scan/dvb-s/IA8-89w34
-rw-r--r--util/scan/dvb-s/Intel4-72.0E6
-rw-r--r--util/scan/dvb-s/Intel904-60.0E13
-rw-r--r--util/scan/dvb-s/Intelsat-1002-1.0W5
-rw-r--r--util/scan/dvb-s/Intelsat-11-43.0W4
-rw-r--r--util/scan/dvb-s/Intelsat-1R-45.0W44
-rw-r--r--util/scan/dvb-s/Intelsat-3R-43.0W35
-rw-r--r--util/scan/dvb-s/Intelsat-6B-43.0W17
-rw-r--r--util/scan/dvb-s/Intelsat-705-50.0W7
-rw-r--r--util/scan/dvb-s/Intelsat-707-53.0W5
-rw-r--r--util/scan/dvb-s/Intelsat-805-55.5W67
-rw-r--r--util/scan/dvb-s/Intelsat-9-58.0W58
-rw-r--r--util/scan/dvb-s/Intelsat-903-34.5W7
-rw-r--r--util/scan/dvb-s/Intelsat-905-24.5W9
-rw-r--r--util/scan/dvb-s/Intelsat-907-27.5W9
-rw-r--r--util/scan/dvb-s/NSS-10-37.5W12
-rw-r--r--util/scan/dvb-s/NSS-7-22.0W25
-rw-r--r--util/scan/dvb-s/NSS-806-40.5W108
-rw-r--r--util/scan/dvb-s/Nahuel-1-71.8W11
-rw-r--r--util/scan/dvb-s/Nilesat101+102-7.0W36
-rw-r--r--util/scan/dvb-s/OptusC1-156E20
-rw-r--r--util/scan/dvb-s/SBS6-74w4
-rw-r--r--util/scan/dvb-s/Satmex-5-116.8W72
-rw-r--r--util/scan/dvb-s/Satmex-6-113.0W19
-rw-r--r--util/scan/dvb-s/Telstar-12-15.0W32
-rw-r--r--util/scan/dvb-s/Turksat-42.0E1
-rw-r--r--util/scan/dvb-s/Yamal201-90.0E48
-rw-r--r--util/scan/dvb-t/at-Offical25
-rw-r--r--util/scan/dvb-t/au-Adelaide (renamed from util/scan/dvb-t/au-sydney_north_shore)6
-rw-r--r--util/scan/dvb-t/au-Brisbane12
-rw-r--r--util/scan/dvb-t/au-Cairns12
-rw-r--r--util/scan/dvb-t/au-Canberra-Black-Mt12
-rw-r--r--util/scan/dvb-t/au-Darwin8
-rw-r--r--util/scan/dvb-t/au-GoldCoast21
-rw-r--r--util/scan/dvb-t/au-Hobart12
-rw-r--r--util/scan/dvb-t/au-Mackay14
-rw-r--r--util/scan/dvb-t/au-Melbourne12
-rw-r--r--util/scan/dvb-t/au-Melbourne-Upwey12
-rw-r--r--util/scan/dvb-t/au-MidNorthCoast22
-rw-r--r--util/scan/dvb-t/au-Newcastle12
-rw-r--r--util/scan/dvb-t/au-Perth12
-rw-r--r--util/scan/dvb-t/au-Perth_Roleystone12
-rw-r--r--util/scan/dvb-t/au-SpencerGulf8
-rwxr-xr-xutil/scan/dvb-t/au-SunshineCoast12
-rw-r--r--util/scan/dvb-t/au-Sydney_Kings_Cross14
-rw-r--r--util/scan/dvb-t/au-Sydney_North_Shore16
-rw-r--r--util/scan/dvb-t/au-Tamworth38
-rw-r--r--util/scan/dvb-t/au-Townsville12
-rw-r--r--util/scan/dvb-t/au-WaggaWagga12
-rw-r--r--util/scan/dvb-t/au-Wollongong40
-rw-r--r--util/scan/dvb-t/au-canberra2
-rw-r--r--util/scan/dvb-t/be-Libramont10
-rw-r--r--util/scan/dvb-t/be-Schoten3
-rw-r--r--util/scan/dvb-t/be-St_Pieters_Leeuw3
-rw-r--r--util/scan/dvb-t/be-Tournai3
-rw-r--r--util/scan/dvb-t/ch-All29
-rw-r--r--util/scan/dvb-t/ch-Citycable14
-rw-r--r--util/scan/dvb-t/cz-Brno4
-rw-r--r--util/scan/dvb-t/cz-Domazlice3
-rw-r--r--util/scan/dvb-t/cz-Ostrava3
-rw-r--r--util/scan/dvb-t/cz-Praha5
-rw-r--r--util/scan/dvb-t/de-Aachen_Stadt6
-rw-r--r--util/scan/dvb-t/de-Berlin12
-rw-r--r--util/scan/dvb-t/de-Bielefeld7
-rw-r--r--util/scan/dvb-t/de-Braunschweig7
-rw-r--r--util/scan/dvb-t/de-Bremen9
-rw-r--r--util/scan/dvb-t/de-Brocken_Magdeburg7
-rw-r--r--util/scan/dvb-t/de-Chemnitz5
-rw-r--r--util/scan/dvb-t/de-Dresden5
-rw-r--r--util/scan/dvb-t/de-Erfurt-Weimar5
-rw-r--r--util/scan/dvb-t/de-Frankfurt41
-rw-r--r--util/scan/dvb-t/de-Freiburg5
-rw-r--r--util/scan/dvb-t/de-HalleSaale6
-rw-r--r--util/scan/dvb-t/de-Hamburg15
-rw-r--r--util/scan/dvb-t/de-Hannover7
-rw-r--r--util/scan/dvb-t/de-Kassel31
-rw-r--r--util/scan/dvb-t/de-Kiel8
-rw-r--r--util/scan/dvb-t/de-Koeln-Bonn9
-rw-r--r--util/scan/dvb-t/de-Leipzig5
-rw-r--r--util/scan/dvb-t/de-Loerrach19
-rw-r--r--util/scan/dvb-t/de-Luebeck7
-rw-r--r--util/scan/dvb-t/de-Muenchen10
-rw-r--r--util/scan/dvb-t/de-Nuernberg8
-rw-r--r--util/scan/dvb-t/de-Osnabrueck5
-rw-r--r--util/scan/dvb-t/de-Ostbayern11
-rw-r--r--util/scan/dvb-t/de-Ravensburg8
-rw-r--r--util/scan/dvb-t/de-Rostock4
-rw-r--r--util/scan/dvb-t/de-Ruhrgebiet19
-rw-r--r--util/scan/dvb-t/de-Schwerin4
-rw-r--r--util/scan/dvb-t/de-Stuttgart6
-rw-r--r--util/scan/dvb-t/de-Wuerzburg7
-rw-r--r--util/scan/dvb-t/dk-All16
-rw-r--r--util/scan/dvb-t/es-Albacete8
-rw-r--r--util/scan/dvb-t/es-Alfabia8
-rw-r--r--util/scan/dvb-t/es-Alicante9
-rw-r--r--util/scan/dvb-t/es-Alpicat8
-rw-r--r--util/scan/dvb-t/es-Asturias8
-rw-r--r--util/scan/dvb-t/es-Bilbao6
-rw-r--r--util/scan/dvb-t/es-Carceres10
-rw-r--r--util/scan/dvb-t/es-Collserola12
-rw-r--r--util/scan/dvb-t/es-Donostia14
-rw-r--r--util/scan/dvb-t/es-Las_Palmas8
-rw-r--r--util/scan/dvb-t/es-Lugo9
-rw-r--r--util/scan/dvb-t/es-Madrid8
-rw-r--r--util/scan/dvb-t/es-Malaga9
-rw-r--r--util/scan/dvb-t/es-Mussara8
-rw-r--r--util/scan/dvb-t/es-Rocacorba6
-rw-r--r--util/scan/dvb-t/es-Santander7
-rw-r--r--util/scan/dvb-t/es-Sevilla8
-rw-r--r--util/scan/dvb-t/es-Valladolid7
-rw-r--r--util/scan/dvb-t/es-Vilamarxant4
-rw-r--r--util/scan/dvb-t/es-Zaragoza7
-rw-r--r--util/scan/dvb-t/fi-Aanekoski6
-rw-r--r--util/scan/dvb-t/fi-Aanekoski_Konginkangas5
-rw-r--r--util/scan/dvb-t/fi-Ahtari4
-rw-r--r--util/scan/dvb-t/fi-Ala-Vuokki4
-rw-r--r--util/scan/dvb-t/fi-Alajarvi5
-rw-r--r--util/scan/dvb-t/fi-Ammansaari4
-rw-r--r--util/scan/dvb-t/fi-Anjalankoski6
-rw-r--r--util/scan/dvb-t/fi-Enontekio_Ahovaara_Raattama4
-rw-r--r--util/scan/dvb-t/fi-Espoo5
-rw-r--r--util/scan/dvb-t/fi-Eurajoki6
-rw-r--r--util/scan/dvb-t/fi-Fiskars6
-rw-r--r--util/scan/dvb-t/fi-Haapavesi6
-rw-r--r--util/scan/dvb-t/fi-Hameenkyro_Kyroskoski5
-rw-r--r--util/scan/dvb-t/fi-Hameenlinna_Painokangas5
-rw-r--r--util/scan/dvb-t/fi-Hanko5
-rw-r--r--util/scan/dvb-t/fi-Hartola4
-rw-r--r--util/scan/dvb-t/fi-Heinavesi4
-rw-r--r--util/scan/dvb-t/fi-Heinola6
-rw-r--r--util/scan/dvb-t/fi-Hetta4
-rw-r--r--util/scan/dvb-t/fi-Houtskari5
-rw-r--r--util/scan/dvb-t/fi-Hyrynsalmi4
-rw-r--r--util/scan/dvb-t/fi-Hyrynsalmi_Kyparavaara4
-rw-r--r--util/scan/dvb-t/fi-Hyrynsalmi_Paljakka4
-rw-r--r--util/scan/dvb-t/fi-Hyvinkaa_Musta-Mannisto5
-rw-r--r--util/scan/dvb-t/fi-Ii_Raiskio4
-rw-r--r--util/scan/dvb-t/fi-Iisalmi4
-rw-r--r--util/scan/dvb-t/fi-Ikaalinen5
-rw-r--r--util/scan/dvb-t/fi-Ikaalinen_Riitiala5
-rw-r--r--util/scan/dvb-t/fi-Inari4
-rw-r--r--util/scan/dvb-t/fi-Ivalo_Saarineitamovaara4
-rw-r--r--util/scan/dvb-t/fi-Jalasjarvi5
-rw-r--r--util/scan/dvb-t/fi-Jamsa_Kaipola5
-rw-r--r--util/scan/dvb-t/fi-Jamsa_Kuorevesi_Halli5
-rw-r--r--util/scan/dvb-t/fi-Jamsa_Matkosvuori6
-rw-r--r--util/scan/dvb-t/fi-Jamsa_Ouninpohja4
-rw-r--r--util/scan/dvb-t/fi-Jamsankoski5
-rw-r--r--util/scan/dvb-t/fi-Joensuu_Vestinkallio4
-rw-r--r--util/scan/dvb-t/fi-Joroinen_Puukkola4
-rw-r--r--util/scan/dvb-t/fi-Joutsa_Lankia5
-rw-r--r--util/scan/dvb-t/fi-Joutseno6
-rw-r--r--util/scan/dvb-t/fi-Juntusranta4
-rw-r--r--util/scan/dvb-t/fi-Juupajoki_Kopsamo4
-rw-r--r--util/scan/dvb-t/fi-Jyvaskyla6
-rw-r--r--util/scan/dvb-t/fi-Jyvaskylan_mlk_Vaajakoski4
-rw-r--r--util/scan/dvb-t/fi-Kaavi_Sivakkavaara_Luikonlahti4
-rw-r--r--util/scan/dvb-t/fi-Kajaani_Pollyvaara4
-rw-r--r--util/scan/dvb-t/fi-Kalajoki4
-rw-r--r--util/scan/dvb-t/fi-Kangaslampi5
-rw-r--r--util/scan/dvb-t/fi-Kangasniemi_Turkinmaki5
-rw-r--r--util/scan/dvb-t/fi-Kankaanpaa5
-rw-r--r--util/scan/dvb-t/fi-Karigasniemi4
-rw-r--r--util/scan/dvb-t/fi-Karkkila6
-rw-r--r--util/scan/dvb-t/fi-Karstula4
-rw-r--r--util/scan/dvb-t/fi-Karvia5
-rw-r--r--util/scan/dvb-t/fi-Kaunispaa4
-rw-r--r--util/scan/dvb-t/fi-Kemijarvi_Suomutunturi4
-rw-r--r--util/scan/dvb-t/fi-Kerimaki6
-rw-r--r--util/scan/dvb-t/fi-Keuruu6
-rw-r--r--util/scan/dvb-t/fi-Keuruu_Haapamaki5
-rw-r--r--util/scan/dvb-t/fi-Kihnio5
-rw-r--r--util/scan/dvb-t/fi-Kiihtelysvaara4
-rw-r--r--util/scan/dvb-t/fi-Kilpisjarvi4
-rw-r--r--util/scan/dvb-t/fi-Kittila_Sirkka_Levitunturi4
-rw-r--r--util/scan/dvb-t/fi-Kolari_Vuolittaja4
-rw-r--r--util/scan/dvb-t/fi-Koli6
-rw-r--r--util/scan/dvb-t/fi-Korpilahti_Vaarunvuori5
-rw-r--r--util/scan/dvb-t/fi-Korppoo5
-rw-r--r--util/scan/dvb-t/fi-Kruunupyy6
-rw-r--r--util/scan/dvb-t/fi-Kuhmo_Iivantiira4
-rw-r--r--util/scan/dvb-t/fi-Kuhmo_Lentiira (renamed from util/scan/dvb-t/se-Gavle)4
-rw-r--r--util/scan/dvb-t/fi-Kuhmoinen5
-rw-r--r--util/scan/dvb-t/fi-Kuhmoinen_Harjunsalmi5
-rw-r--r--util/scan/dvb-t/fi-Kuhmoinen_Puukkoinen4
-rw-r--r--util/scan/dvb-t/fi-Kuopio6
-rw-r--r--util/scan/dvb-t/fi-Kustavi_Viherlahti5
-rw-r--r--util/scan/dvb-t/fi-Kuttanen4
-rw-r--r--util/scan/dvb-t/fi-Kyyjarvi_Noposenaho4
-rw-r--r--util/scan/dvb-t/fi-Lahti6
-rw-r--r--util/scan/dvb-t/fi-Lapua6
-rw-r--r--util/scan/dvb-t/fi-Laukaa5
-rw-r--r--util/scan/dvb-t/fi-Laukaa_Vihtavuori5
-rw-r--r--util/scan/dvb-t/fi-Lavia_Lavianjarvi4
-rw-r--r--util/scan/dvb-t/fi-Lieksa_Vieki5
-rw-r--r--util/scan/dvb-t/fi-Lohja6
-rw-r--r--util/scan/dvb-t/fi-Loimaa5
-rw-r--r--util/scan/dvb-t/fi-Luhanka5
-rw-r--r--util/scan/dvb-t/fi-Luopioinen5
-rw-r--r--util/scan/dvb-t/fi-Mantta5
-rw-r--r--util/scan/dvb-t/fi-Mantyharju4
-rw-r--r--util/scan/dvb-t/fi-Mikkeli6
-rw-r--r--util/scan/dvb-t/fi-Muonio_Olostunturi4
-rw-r--r--util/scan/dvb-t/fi-Nilsia5
-rw-r--r--util/scan/dvb-t/fi-Nilsia_Keski-Siikajarvi4
-rw-r--r--util/scan/dvb-t/fi-Nilsia_Pisa4
-rw-r--r--util/scan/dvb-t/fi-Nokia6
-rw-r--r--util/scan/dvb-t/fi-Nokia_Siuro_Linnavuori5
-rw-r--r--util/scan/dvb-t/fi-Nummi-Pusula_Hyonola5
-rw-r--r--util/scan/dvb-t/fi-Nurmes_Porokyla4
-rw-r--r--util/scan/dvb-t/fi-Orivesi_Langelmaki_Talviainen4
-rw-r--r--util/scan/dvb-t/fi-Oulu6
-rw-r--r--util/scan/dvb-t/fi-Padasjoki5
-rw-r--r--util/scan/dvb-t/fi-Padasjoki_Arrakoski5
-rw-r--r--util/scan/dvb-t/fi-Paltamo_Kivesvaara4
-rw-r--r--util/scan/dvb-t/fi-Parikkala4
-rw-r--r--util/scan/dvb-t/fi-Parkano5
-rw-r--r--util/scan/dvb-t/fi-Pello4
-rw-r--r--util/scan/dvb-t/fi-Pello_Ratasvaara4
-rw-r--r--util/scan/dvb-t/fi-Perho5
-rw-r--r--util/scan/dvb-t/fi-Pernaja5
-rw-r--r--util/scan/dvb-t/fi-Pieksamaki_Halkokumpu4
-rw-r--r--util/scan/dvb-t/fi-Pihtipudas5
-rw-r--r--util/scan/dvb-t/fi-Porvoo_Suomenkyla5
-rw-r--r--util/scan/dvb-t/fi-Posio4
-rw-r--r--util/scan/dvb-t/fi-Pudasjarvi4
-rw-r--r--util/scan/dvb-t/fi-Pudasjarvi_Iso-Syote4
-rw-r--r--util/scan/dvb-t/fi-Pudasjarvi_Kangasvaara4
-rw-r--r--util/scan/dvb-t/fi-Puolanka5
-rw-r--r--util/scan/dvb-t/fi-Pyhatunturi4
-rw-r--r--util/scan/dvb-t/fi-Pyhavuori5
-rw-r--r--util/scan/dvb-t/fi-Pylkonmaki_Karankajarvi4
-rw-r--r--util/scan/dvb-t/fi-Raahe_Mestauskallio5
-rw-r--r--util/scan/dvb-t/fi-Raahe_Piehinki4
-rw-r--r--util/scan/dvb-t/fi-Ranua_Haasionmaa4
-rw-r--r--util/scan/dvb-t/fi-Ranua_Leppiaho4
-rw-r--r--util/scan/dvb-t/fi-Rautavaara_Angervikko5
-rw-r--r--util/scan/dvb-t/fi-Rautjarvi_Simpele4
-rw-r--r--util/scan/dvb-t/fi-Ristijarvi4
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi5
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi_Ala-Nampa_Yli-Nampa_Rantalaki4
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi_Kaihuanvaara4
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi_Karhuvaara_Marrasjarvi4
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi_Marasenkallio4
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi_Meltaus_Sorviselka4
-rw-r--r--util/scan/dvb-t/fi-Rovaniemi_Sonka4
-rw-r--r--util/scan/dvb-t/fi-Ruka5
-rw-r--r--util/scan/dvb-t/fi-Ruovesi_Storminiemi5
-rw-r--r--util/scan/dvb-t/fi-Saarijarvi5
-rw-r--r--util/scan/dvb-t/fi-Saarijarvi_Kalmari4
-rw-r--r--util/scan/dvb-t/fi-Saarijarvi_Mahlu4
-rw-r--r--util/scan/dvb-t/fi-Salla_Hirvasvaara4
-rw-r--r--util/scan/dvb-t/fi-Salla_Ihistysjanka4
-rw-r--r--util/scan/dvb-t/fi-Salla_Naruska4
-rw-r--r--util/scan/dvb-t/fi-Salla_Saija4
-rw-r--r--util/scan/dvb-t/fi-Salla_Sallatunturi4
-rw-r--r--util/scan/dvb-t/fi-Salo_Isokyla6
-rw-r--r--util/scan/dvb-t/fi-Savukoski_Martti_Haarahonganmaa4
-rw-r--r--util/scan/dvb-t/fi-Savukoski_Tanhua4
-rw-r--r--util/scan/dvb-t/fi-Siilinjarvi5
-rw-r--r--util/scan/dvb-t/fi-Sipoo_Galthagen5
-rw-r--r--util/scan/dvb-t/fi-Sodankyla_Pittiovaara4
-rw-r--r--util/scan/dvb-t/fi-Sulkava_Vaatalanmaki4
-rw-r--r--util/scan/dvb-t/fi-Sysma_Liikola5
-rw-r--r--util/scan/dvb-t/fi-Taivalkoski4
-rw-r--r--util/scan/dvb-t/fi-Taivalkoski_Taivalvaara4
-rw-r--r--util/scan/dvb-t/fi-Tammela6
-rw-r--r--util/scan/dvb-t/fi-Tammisaari5
-rw-r--r--util/scan/dvb-t/fi-Tampere4
-rw-r--r--util/scan/dvb-t/fi-Tampere_Pyynikki6
-rw-r--r--util/scan/dvb-t/fi-Tervola5
-rw-r--r--util/scan/dvb-t/fi-Turku5
-rw-r--r--util/scan/dvb-t/fi-Utsjoki4
-rw-r--r--util/scan/dvb-t/fi-Utsjoki_Nuorgam_Njallavaara4
-rw-r--r--util/scan/dvb-t/fi-Utsjoki_Nuorgam_raja4
-rw-r--r--util/scan/dvb-t/fi-Utsjoki_Outakoski4
-rw-r--r--util/scan/dvb-t/fi-Utsjoki_Polvarniemi4
-rw-r--r--util/scan/dvb-t/fi-Utsjoki_Rovisuvanto4
-rw-r--r--util/scan/dvb-t/fi-Utsjoki_Tenola4
-rw-r--r--util/scan/dvb-t/fi-Uusikaupunki_Orivo5
-rw-r--r--util/scan/dvb-t/fi-Vaala4
-rw-r--r--util/scan/dvb-t/fi-Vaasa5
-rw-r--r--util/scan/dvb-t/fi-Valtimo4
-rw-r--r--util/scan/dvb-t/fi-Vammala_Jyranvuori5
-rw-r--r--util/scan/dvb-t/fi-Vammala_Roismala4
-rw-r--r--util/scan/dvb-t/fi-Vammala_Savi4
-rw-r--r--util/scan/dvb-t/fi-Vantaa_Hakunila6
-rw-r--r--util/scan/dvb-t/fi-Varpaisjarvi_Honkamaki5
-rw-r--r--util/scan/dvb-t/fi-Virrat_Lappavuori5
-rw-r--r--util/scan/dvb-t/fi-Vuokatti6
-rw-r--r--util/scan/dvb-t/fi-Vuotso4
-rw-r--r--util/scan/dvb-t/fi-Ylitornio_Ainiovaara5
-rw-r--r--util/scan/dvb-t/fi-Ylitornio_Raanujarvi4
-rw-r--r--util/scan/dvb-t/fi-Yllas4
-rw-r--r--util/scan/dvb-t/fr-Abbeville25
-rw-r--r--util/scan/dvb-t/fr-Agen25
-rw-r--r--util/scan/dvb-t/fr-Ajaccio25
-rw-r--r--util/scan/dvb-t/fr-Albi25
-rw-r--r--util/scan/dvb-t/fr-Alençon25
-rw-r--r--util/scan/dvb-t/fr-Ales25
-rw-r--r--util/scan/dvb-t/fr-Ales-Bouquet25
-rw-r--r--util/scan/dvb-t/fr-Amiens25
-rw-r--r--util/scan/dvb-t/fr-Angers25
-rw-r--r--util/scan/dvb-t/fr-Annecy25
-rw-r--r--util/scan/dvb-t/fr-Arcachon25
-rw-r--r--util/scan/dvb-t/fr-Argenton25
-rw-r--r--util/scan/dvb-t/fr-Aubenas25
-rw-r--r--util/scan/dvb-t/fr-Aurillac25
-rw-r--r--util/scan/dvb-t/fr-Autun25
-rw-r--r--util/scan/dvb-t/fr-Auxerre25
-rw-r--r--util/scan/dvb-t/fr-Avignon25
-rw-r--r--util/scan/dvb-t/fr-BarleDuc25
-rw-r--r--util/scan/dvb-t/fr-Bastia25
-rw-r--r--util/scan/dvb-t/fr-Bayonne25
-rw-r--r--util/scan/dvb-t/fr-Bergerac25
-rw-r--r--util/scan/dvb-t/fr-Besançon25
-rw-r--r--util/scan/dvb-t/fr-Bordeaux9
-rw-r--r--util/scan/dvb-t/fr-Bordeaux-Bouliac25
-rw-r--r--util/scan/dvb-t/fr-Bordeaux-Cauderan25
-rw-r--r--util/scan/dvb-t/fr-Boulogne25
-rw-r--r--util/scan/dvb-t/fr-Bourges25
-rw-r--r--util/scan/dvb-t/fr-Brest9
-rw-r--r--util/scan/dvb-t/fr-Brive25
-rw-r--r--util/scan/dvb-t/fr-Caen25
-rw-r--r--util/scan/dvb-t/fr-Caen-Pincon25
-rw-r--r--util/scan/dvb-t/fr-Cannes25
-rw-r--r--util/scan/dvb-t/fr-Carcassonne25
-rw-r--r--util/scan/dvb-t/fr-Chambery30
-rw-r--r--util/scan/dvb-t/fr-Chartres25
-rw-r--r--util/scan/dvb-t/fr-Chennevieres25
-rw-r--r--util/scan/dvb-t/fr-Cherbourg25
-rw-r--r--util/scan/dvb-t/fr-ClermontFerrand25
-rw-r--r--util/scan/dvb-t/fr-Cluses30
-rw-r--r--util/scan/dvb-t/fr-Dieppe25
-rw-r--r--util/scan/dvb-t/fr-Dijon30
-rw-r--r--util/scan/dvb-t/fr-Dunkerque30
-rw-r--r--util/scan/dvb-t/fr-Epinal25
-rw-r--r--util/scan/dvb-t/fr-Evreux25
-rw-r--r--util/scan/dvb-t/fr-Forbach30
-rw-r--r--util/scan/dvb-t/fr-Gex30
-rw-r--r--util/scan/dvb-t/fr-Grenoble25
-rw-r--r--util/scan/dvb-t/fr-Gueret25
-rw-r--r--util/scan/dvb-t/fr-Hirson30
-rw-r--r--util/scan/dvb-t/fr-Hyeres25
-rw-r--r--util/scan/dvb-t/fr-LaRochelle25
-rw-r--r--util/scan/dvb-t/fr-Laval25
-rw-r--r--util/scan/dvb-t/fr-LeCreusot25
-rw-r--r--util/scan/dvb-t/fr-LeHavre25
-rw-r--r--util/scan/dvb-t/fr-LeMans21
-rw-r--r--util/scan/dvb-t/fr-LePuyEnVelay25
-rw-r--r--util/scan/dvb-t/fr-Lille30
-rw-r--r--util/scan/dvb-t/fr-Lille-Lambersart25
-rw-r--r--util/scan/dvb-t/fr-LilleT213
-rw-r--r--util/scan/dvb-t/fr-Limoges25
-rw-r--r--util/scan/dvb-t/fr-Longwy30
-rw-r--r--util/scan/dvb-t/fr-Lorient25
-rw-r--r--util/scan/dvb-t/fr-Lyon-Fourviere19
-rw-r--r--util/scan/dvb-t/fr-Lyon-Pilat17
-rw-r--r--util/scan/dvb-t/fr-Macon30
-rw-r--r--util/scan/dvb-t/fr-Mantes25
-rw-r--r--util/scan/dvb-t/fr-Marseille6
-rw-r--r--util/scan/dvb-t/fr-Maubeuge30
-rw-r--r--util/scan/dvb-t/fr-Meaux25
-rw-r--r--util/scan/dvb-t/fr-Mende25
-rw-r--r--util/scan/dvb-t/fr-Menton25
-rw-r--r--util/scan/dvb-t/fr-Metz30
-rw-r--r--util/scan/dvb-t/fr-Mezieres30
-rw-r--r--util/scan/dvb-t/fr-Montlucon25
-rw-r--r--util/scan/dvb-t/fr-Montpellier25
-rw-r--r--util/scan/dvb-t/fr-Mulhouse26
-rw-r--r--util/scan/dvb-t/fr-Nancy25
-rw-r--r--util/scan/dvb-t/fr-Nantes8
-rw-r--r--util/scan/dvb-t/fr-NeufchatelEnBray25
-rw-r--r--util/scan/dvb-t/fr-Nice25
-rw-r--r--util/scan/dvb-t/fr-Niort7
-rw-r--r--util/scan/dvb-t/fr-Orleans17
-rw-r--r--util/scan/dvb-t/fr-Paris19
-rw-r--r--util/scan/dvb-t/fr-Parthenay25
-rw-r--r--util/scan/dvb-t/fr-Perpignan25
-rw-r--r--util/scan/dvb-t/fr-Poitiers25
-rw-r--r--util/scan/dvb-t/fr-Privas25
-rw-r--r--util/scan/dvb-t/fr-Reims25
-rw-r--r--util/scan/dvb-t/fr-Rennes7
-rw-r--r--util/scan/dvb-t/fr-Roanne25
-rw-r--r--util/scan/dvb-t/fr-Rouen8
-rw-r--r--util/scan/dvb-t/fr-SaintEtienne25
-rw-r--r--util/scan/dvb-t/fr-SaintRaphael25
-rw-r--r--util/scan/dvb-t/fr-Sannois25
-rw-r--r--util/scan/dvb-t/fr-Sarrebourg30
-rw-r--r--util/scan/dvb-t/fr-Sens25
-rw-r--r--util/scan/dvb-t/fr-Strasbourg30
-rw-r--r--util/scan/dvb-t/fr-Toulon25
-rw-r--r--util/scan/dvb-t/fr-Toulouse8
-rw-r--r--util/scan/dvb-t/fr-Toulouse-Midi25
-rw-r--r--util/scan/dvb-t/fr-Tours25
-rw-r--r--util/scan/dvb-t/fr-Troyes25
-rw-r--r--util/scan/dvb-t/fr-Ussel25
-rw-r--r--util/scan/dvb-t/fr-Valence25
-rw-r--r--util/scan/dvb-t/fr-Valenciennes30
-rw-r--r--util/scan/dvb-t/fr-Vannes7
-rw-r--r--util/scan/dvb-t/fr-Villebon22
-rw-r--r--util/scan/dvb-t/fr-Vittel30
-rw-r--r--util/scan/dvb-t/fr-Voiron30
-rw-r--r--util/scan/dvb-t/gr-Athens3
-rw-r--r--util/scan/dvb-t/hr-Zagreb3
-rw-r--r--util/scan/dvb-t/is-Reykjavik13
-rw-r--r--util/scan/dvb-t/it-Aosta21
-rw-r--r--util/scan/dvb-t/it-Bari18
-rw-r--r--util/scan/dvb-t/it-Bologna28
-rw-r--r--util/scan/dvb-t/it-Bolzano5
-rw-r--r--util/scan/dvb-t/it-Cagliari31
-rw-r--r--util/scan/dvb-t/it-Caivano14
-rw-r--r--util/scan/dvb-t/it-Catania27
-rw-r--r--util/scan/dvb-t/it-Conero8
-rw-r--r--util/scan/dvb-t/it-Firenze20
-rw-r--r--util/scan/dvb-t/it-Genova12
-rw-r--r--util/scan/dvb-t/it-Livorno15
-rw-r--r--util/scan/dvb-t/it-Milano15
-rw-r--r--util/scan/dvb-t/it-Pagnacco27
-rw-r--r--util/scan/dvb-t/it-Palermo23
-rw-r--r--util/scan/dvb-t/it-Pisa18
-rw-r--r--util/scan/dvb-t/it-Roma16
-rw-r--r--util/scan/dvb-t/it-Sassari33
-rw-r--r--util/scan/dvb-t/it-Torino13
-rw-r--r--util/scan/dvb-t/it-Trieste23
-rw-r--r--util/scan/dvb-t/it-Varese16
-rw-r--r--util/scan/dvb-t/it-Venezia19
-rw-r--r--util/scan/dvb-t/lu-All5
-rw-r--r--util/scan/dvb-t/lv-Riga25
-rw-r--r--util/scan/dvb-t/nl-All38
-rw-r--r--util/scan/dvb-t/nl-AlphenaandenRijn7
-rw-r--r--util/scan/dvb-t/nl-Randstad7
-rw-r--r--util/scan/dvb-t/nz-Waiatarua13
-rw-r--r--util/scan/dvb-t/pl-Wroclaw3
-rw-r--r--util/scan/dvb-t/se-Alvdalen_Brunnsberg3
-rw-r--r--util/scan/dvb-t/se-Alvdalsasen3
-rw-r--r--util/scan/dvb-t/se-Alvsbyn7
-rw-r--r--util/scan/dvb-t/se-Amot3
-rw-r--r--util/scan/dvb-t/se-Ange_Snoberg6
-rw-r--r--util/scan/dvb-t/se-Angebo3
-rw-r--r--util/scan/dvb-t/se-Angelholm_Vegeholm7
-rw-r--r--util/scan/dvb-t/se-Arvidsjaur_Jultrask6
-rw-r--r--util/scan/dvb-t/se-Aspeboda3
-rw-r--r--util/scan/dvb-t/se-Atvidaberg4
-rw-r--r--util/scan/dvb-t/se-Avesta_Krylbo4
-rw-r--r--util/scan/dvb-t/se-Backefors7
-rw-r--r--util/scan/dvb-t/se-Bankeryd4
-rw-r--r--util/scan/dvb-t/se-Bergsjo_Balleberget3
-rw-r--r--util/scan/dvb-t/se-Bergvik3
-rw-r--r--util/scan/dvb-t/se-Bollebygd4
-rw-r--r--util/scan/dvb-t/se-Bollnas6
-rw-r--r--util/scan/dvb-t/se-Boras_Dalsjofors7
-rw-r--r--util/scan/dvb-t/se-Boras_Sjobo4
-rw-r--r--util/scan/dvb-t/se-Borlange_Idkerberget6
-rw-r--r--util/scan/dvb-t/se-Borlange_Nygardarna4
-rw-r--r--util/scan/dvb-t/se-Bottnaryd_Ryd3
-rw-r--r--util/scan/dvb-t/se-Bromsebro4
-rw-r--r--util/scan/dvb-t/se-Bruzaholm3
-rw-r--r--util/scan/dvb-t/se-Byxelkrok4
-rw-r--r--util/scan/dvb-t/se-Dadran3
-rw-r--r--util/scan/dvb-t/se-Dalfors3
-rw-r--r--util/scan/dvb-t/se-Dalstuga3
-rw-r--r--util/scan/dvb-t/se-Degerfors6
-rw-r--r--util/scan/dvb-t/se-Delary3
-rw-r--r--util/scan/dvb-t/se-Djura3
-rw-r--r--util/scan/dvb-t/se-Drevdagen3
-rw-r--r--util/scan/dvb-t/se-Duvnas3
-rw-r--r--util/scan/dvb-t/se-Duvnas_Basna3
-rw-r--r--util/scan/dvb-t/se-Edsbyn3
-rw-r--r--util/scan/dvb-t/se-Emmaboda_Balshult6
-rw-r--r--util/scan/dvb-t/se-Enviken4
-rw-r--r--util/scan/dvb-t/se-Fagersta4
-rw-r--r--util/scan/dvb-t/se-Falerum_Centrum3
-rw-r--r--util/scan/dvb-t/se-Falun_Lovberget6
-rw-r--r--util/scan/dvb-t/se-Farila3
-rw-r--r--util/scan/dvb-t/se-Faro_Ajkerstrask4
-rw-r--r--util/scan/dvb-t/se-Farosund_Bunge7
-rw-r--r--util/scan/dvb-t/se-Filipstad_Klockarhojden6
-rw-r--r--util/scan/dvb-t/se-Finnveden6
-rw-r--r--util/scan/dvb-t/se-Fredriksberg3
-rw-r--r--util/scan/dvb-t/se-Fritsla3
-rw-r--r--util/scan/dvb-t/se-Furudal3
-rw-r--r--util/scan/dvb-t/se-Gallivare6
-rw-r--r--util/scan/dvb-t/se-Garpenberg_Kuppgarden3
-rw-r--r--util/scan/dvb-t/se-Gavle_Skogmur6
-rw-r--r--util/scan/dvb-t/se-Gnarp3
-rw-r--r--util/scan/dvb-t/se-Gnesta4
-rw-r--r--util/scan/dvb-t/se-Gnosjo_Marieholm3
-rw-r--r--util/scan/dvb-t/se-Goteborg_Brudaremossen7
-rw-r--r--util/scan/dvb-t/se-Goteborg_Slattadamm7
-rw-r--r--util/scan/dvb-t/se-Gullbrandstorp3
-rw-r--r--util/scan/dvb-t/se-Gunnarsbo3
-rw-r--r--util/scan/dvb-t/se-Gusum3
-rw-r--r--util/scan/dvb-t/se-Hagfors_Varmullsasen6
-rw-r--r--util/scan/dvb-t/se-Hallaryd3
-rw-r--r--util/scan/dvb-t/se-Hallbo3
-rw-r--r--util/scan/dvb-t/se-Halmstad_Hamnen4
-rw-r--r--util/scan/dvb-t/se-Halmstad_Oskarstrom6
-rw-r--r--util/scan/dvb-t/se-Harnosand_Harnon6
-rw-r--r--util/scan/dvb-t/se-Hassela3
-rw-r--r--util/scan/dvb-t/se-Havdhem7
-rw-r--r--util/scan/dvb-t/se-Hedemora3
-rw-r--r--util/scan/dvb-t/se-Helsingborg_Olympia7
-rw-r--r--util/scan/dvb-t/se-Hennan3
-rw-r--r--util/scan/dvb-t/se-Hestra_Aspas3
-rw-r--r--util/scan/dvb-t/se-Hjo_Grevback3
-rw-r--r--util/scan/dvb-t/se-Hofors6
-rw-r--r--util/scan/dvb-t/se-Hogfors3
-rw-r--r--util/scan/dvb-t/se-Hogsby_Virstad4
-rw-r--r--util/scan/dvb-t/se-Holsbybrunn_Holsbyholm3
-rw-r--r--util/scan/dvb-t/se-Horby_Sallerup7
-rw-r--r--util/scan/dvb-t/se-Horken3
-rw-r--r--util/scan/dvb-t/se-Hudiksvall_Forsa6
-rw-r--r--util/scan/dvb-t/se-Hudiksvall_Galgberget4
-rw-r--r--util/scan/dvb-t/se-Huskvarna3
-rw-r--r--util/scan/dvb-t/se-Idre3
-rw-r--r--util/scan/dvb-t/se-Ingatorp3
-rw-r--r--util/scan/dvb-t/se-Ingvallsbenning3
-rw-r--r--util/scan/dvb-t/se-Irevik4
-rw-r--r--util/scan/dvb-t/se-Jamjo4
-rw-r--r--util/scan/dvb-t/se-Jarnforsen3
-rw-r--r--util/scan/dvb-t/se-Jarvso3
-rw-r--r--util/scan/dvb-t/se-Jokkmokk_Tjalmejaure6
-rw-r--r--util/scan/dvb-t/se-Jonkoping_Bondberget6
-rw-r--r--util/scan/dvb-t/se-Kalix6
-rw-r--r--util/scan/dvb-t/se-Karbole3
-rw-r--r--util/scan/dvb-t/se-Karlsborg_Vaberget3
-rw-r--r--util/scan/dvb-t/se-Karlshamn6
-rw-r--r--util/scan/dvb-t/se-Karlskrona_Vamo6
-rw-r--r--util/scan/dvb-t/se-Karlstad_Sormon9
-rw-r--r--util/scan/dvb-t/se-Kaxholmen_Vistakulle3
-rw-r--r--util/scan/dvb-t/se-Kinnastrom3
-rw-r--r--util/scan/dvb-t/se-Kiruna_Kirunavaara6
-rw-r--r--util/scan/dvb-t/se-Kisa7
-rw-r--r--util/scan/dvb-t/se-Knared3
-rw-r--r--util/scan/dvb-t/se-Kopmanholmen6
-rw-r--r--util/scan/dvb-t/se-Kopparberg4
-rw-r--r--util/scan/dvb-t/se-Kramfors_Lugnvik6
-rw-r--r--util/scan/dvb-t/se-Kristinehamn_Utsiktsberget6
-rw-r--r--util/scan/dvb-t/se-Kungsater3
-rw-r--r--util/scan/dvb-t/se-Kungsberget_GI3
-rw-r--r--util/scan/dvb-t/se-Langshyttan3
-rw-r--r--util/scan/dvb-t/se-Langshyttan_Engelsfors3
-rw-r--r--util/scan/dvb-t/se-Leksand_Karingberget3
-rw-r--r--util/scan/dvb-t/se-Lerdala3
-rw-r--r--util/scan/dvb-t/se-Lilltjara_Digerberget3
-rw-r--r--util/scan/dvb-t/se-Limedsforsen3
-rw-r--r--util/scan/dvb-t/se-Lindshammar_Ramkvilla3
-rw-r--r--util/scan/dvb-t/se-Linkoping_Vattentornet7
-rw-r--r--util/scan/dvb-t/se-Ljugarn4
-rw-r--r--util/scan/dvb-t/se-Loffstrand6
-rw-r--r--util/scan/dvb-t/se-Lonneberga4
-rw-r--r--util/scan/dvb-t/se-Lorstrand3
-rw-r--r--util/scan/dvb-t/se-Ludvika_Bjorkasen4
-rw-r--r--util/scan/dvb-t/se-Lumsheden_Trekanten3
-rw-r--r--util/scan/dvb-t/se-Lycksele_Knaften6
-rw-r--r--util/scan/dvb-t/se-Mahult3
-rw-r--r--util/scan/dvb-t/se-Malmo_Jagersro7
-rw-r--r--util/scan/dvb-t/se-Malung4
-rw-r--r--util/scan/dvb-t/se-Mariannelund3
-rw-r--r--util/scan/dvb-t/se-Markaryd_Hualtet4
-rw-r--r--util/scan/dvb-t/se-Matfors6
-rw-r--r--util/scan/dvb-t/se-Molnbo_Tallstugan2
-rw-r--r--util/scan/dvb-t/se-Molndal_Vasterberget7
-rw-r--r--util/scan/dvb-t/se-Mora_Eldris6
-rw-r--r--util/scan/dvb-t/se-Motala_Ervasteby7
-rw-r--r--util/scan/dvb-t/se-Mullsjo_Torestorp4
-rw-r--r--util/scan/dvb-t/se-Nassjo6
-rw-r--r--util/scan/dvb-t/se-Navekvarn3
-rw-r--r--util/scan/dvb-t/se-Norrahammar3
-rw-r--r--util/scan/dvb-t/se-Norrkoping_Krokek7
-rw-r--r--util/scan/dvb-t/se-Norrtalje_Sodra_Bergen7
-rw-r--r--util/scan/dvb-t/se-Nykoping3
-rw-r--r--util/scan/dvb-t/se-Orebro_Lockhyttan7
-rw-r--r--util/scan/dvb-t/se-Ornskoldsvik_As6
-rw-r--r--util/scan/dvb-t/se-Oskarshamn6
-rw-r--r--util/scan/dvb-t/se-Ostersund_Brattasen7
-rw-r--r--util/scan/dvb-t/se-Osthammar_Valo7
-rw-r--r--util/scan/dvb-t/se-Overkalix6
-rw-r--r--util/scan/dvb-t/se-Oxberg3
-rw-r--r--util/scan/dvb-t/se-Pajala6
-rw-r--r--util/scan/dvb-t/se-Paulistom3
-rw-r--r--util/scan/dvb-t/se-Rattvik3
-rw-r--r--util/scan/dvb-t/se-Rengsjo3
-rw-r--r--util/scan/dvb-t/se-Rorbacksnas3
-rw-r--r--util/scan/dvb-t/se-Sagmyra3
-rw-r--r--util/scan/dvb-t/se-Salen3
-rw-r--r--util/scan/dvb-t/se-Salfjallet3
-rw-r--r--util/scan/dvb-t/se-Sarna_Mickeltemplet3
-rw-r--r--util/scan/dvb-t/se-Satila3
-rw-r--r--util/scan/dvb-t/se-Saxdalen3
-rw-r--r--util/scan/dvb-t/se-Siljansnas_Uvberget3
-rw-r--r--util/scan/dvb-t/se-Skarstad3
-rw-r--r--util/scan/dvb-t/se-Skattungbyn3
-rw-r--r--util/scan/dvb-t/se-Skelleftea6
-rw-r--r--util/scan/dvb-t/se-Skene_Nycklarberget3
-rw-r--r--util/scan/dvb-t/se-Skovde7
-rw-r--r--util/scan/dvb-t/se-Smedjebacken_Uvberget6
-rw-r--r--util/scan/dvb-t/se-Soderhamn4
-rw-r--r--util/scan/dvb-t/se-Soderkoping4
-rw-r--r--util/scan/dvb-t/se-Sodertalje_Ragnhildsborg7
-rw-r--r--util/scan/dvb-t/se-Solleftea_Hallsta6
-rw-r--r--util/scan/dvb-t/se-Solleftea_Multra6
-rw-r--r--util/scan/dvb-t/se-Sorsjon3
-rw-r--r--util/scan/dvb-t/se-Stockholm_Marieberg7
-rw-r--r--util/scan/dvb-t/se-Stockholm_Nacka8
-rw-r--r--util/scan/dvb-t/se-Stora_Skedvi3
-rw-r--r--util/scan/dvb-t/se-Storfjaten3
-rw-r--r--util/scan/dvb-t/se-Storuman6
-rw-r--r--util/scan/dvb-t/se-Stromstad7
-rw-r--r--util/scan/dvb-t/se-Styrsjobo3
-rw-r--r--util/scan/dvb-t/se-Sundborn3
-rw-r--r--util/scan/dvb-t/se-Sundsbruk6
-rw-r--r--util/scan/dvb-t/se-Sundsvall_S_Stadsberget7
-rw-r--r--util/scan/dvb-t/se-Sunne_Blabarskullen6
-rw-r--r--util/scan/dvb-t/se-Svartnas3
-rw-r--r--util/scan/dvb-t/se-Sveg_Brickan6
-rw-r--r--util/scan/dvb-t/se-Taberg3
-rw-r--r--util/scan/dvb-t/se-Tandadalen3
-rw-r--r--util/scan/dvb-t/se-Tasjo6
-rw-r--r--util/scan/dvb-t/se-Tollsjo3
-rw-r--r--util/scan/dvb-t/se-Torsby_Bada6
-rw-r--r--util/scan/dvb-t/se-Tranas_Bredkarr4
-rw-r--r--util/scan/dvb-t/se-Tranemo3
-rw-r--r--util/scan/dvb-t/se-Transtrand_Bolheden4
-rw-r--r--util/scan/dvb-t/se-Traryd_Betas4
-rw-r--r--util/scan/dvb-t/se-Trollhattan7
-rw-r--r--util/scan/dvb-t/se-Trosa4
-rw-r--r--util/scan/dvb-t/se-Tystberga3
-rw-r--r--util/scan/dvb-t/se-Uddevalla_Herrestad7
-rw-r--r--util/scan/dvb-t/se-Ullared3
-rw-r--r--util/scan/dvb-t/se-Ulricehamn4
-rw-r--r--util/scan/dvb-t/se-Ulvshyttan_Porjus3
-rw-r--r--util/scan/dvb-t/se-Uppsala_Rickomberga3
-rw-r--r--util/scan/dvb-t/se-Uppsala_Vedyxa7
-rw-r--r--util/scan/dvb-t/se-Vaddo_Elmsta4
-rw-r--r--util/scan/dvb-t/se-Valdemarsvik4
-rw-r--r--util/scan/dvb-t/se-Vannas_Granlundsberget6
-rw-r--r--util/scan/dvb-t/se-Vansbro_Hummelberget3
-rw-r--r--util/scan/dvb-t/se-Varberg_Grimeton6
-rw-r--r--util/scan/dvb-t/se-Vasteras_Lillharad7
-rw-r--r--util/scan/dvb-t/se-Vastervik_Farhult6
-rw-r--r--util/scan/dvb-t/se-Vaxbo3
-rw-r--r--util/scan/dvb-t/se-Vessigebro3
-rw-r--r--util/scan/dvb-t/se-Vetlanda_Nye3
-rw-r--r--util/scan/dvb-t/se-Vikmanshyttan3
-rw-r--r--util/scan/dvb-t/se-Virserum6
-rw-r--r--util/scan/dvb-t/se-Visby_Follingbo7
-rw-r--r--util/scan/dvb-t/se-Visby_Hamnen7
-rw-r--r--util/scan/dvb-t/se-Visingso3
-rw-r--r--util/scan/dvb-t/se-Vislanda_Nydala6
-rw-r--r--util/scan/dvb-t/se-Voxna3
-rw-r--r--util/scan/dvb-t/se-Ystad_Metallgatan7
-rw-r--r--util/scan/dvb-t/se-Yttermalung3
-rw-r--r--util/scan/dvb-t/sk-BanskaBystrica4
-rw-r--r--util/scan/dvb-t/sk-Bratislava4
-rw-r--r--util/scan/dvb-t/sk-Kosice4
-rw-r--r--util/scan/dvb-t/tw-Kaohsiung6
-rw-r--r--util/scan/dvb-t/tw-Taipei7
-rw-r--r--util/scan/dvb-t/uk-Aberdare10
-rw-r--r--util/scan/dvb-t/uk-Angus10
-rw-r--r--util/scan/dvb-t/uk-BeaconHill10
-rw-r--r--util/scan/dvb-t/uk-Belmont10
-rw-r--r--util/scan/dvb-t/uk-Bilsdale10
-rw-r--r--util/scan/dvb-t/uk-BlackHill11
-rw-r--r--util/scan/dvb-t/uk-Blaenplwyf10
-rw-r--r--util/scan/dvb-t/uk-BluebellHill10
-rw-r--r--util/scan/dvb-t/uk-Bressay10
-rw-r--r--util/scan/dvb-t/uk-BrierleyHill10
-rw-r--r--util/scan/dvb-t/uk-BristolIlchesterCres10
-rw-r--r--util/scan/dvb-t/uk-BristolKingsWeston10
-rw-r--r--util/scan/dvb-t/uk-Bromsgrove10
-rw-r--r--util/scan/dvb-t/uk-BrougherMountain10
-rw-r--r--util/scan/dvb-t/uk-Caldbeck10
-rw-r--r--util/scan/dvb-t/uk-CaradonHill10
-rw-r--r--util/scan/dvb-t/uk-Carmel10
-rw-r--r--util/scan/dvb-t/uk-Chatton10
-rw-r--r--util/scan/dvb-t/uk-Chesterfield10
-rw-r--r--util/scan/dvb-t/uk-Craigkelly10
-rw-r--r--util/scan/dvb-t/uk-CrystalPalace11
-rw-r--r--util/scan/dvb-t/uk-Darvel10
-rw-r--r--util/scan/dvb-t/uk-Divis10
-rw-r--r--util/scan/dvb-t/uk-Dover14
-rw-r--r--util/scan/dvb-t/uk-Durris10
-rw-r--r--util/scan/dvb-t/uk-Eitshal10
-rw-r--r--util/scan/dvb-t/uk-EmleyMoor10
-rw-r--r--util/scan/dvb-t/uk-Fenham10
-rw-r--r--util/scan/dvb-t/uk-Fenton10
-rw-r--r--util/scan/dvb-t/uk-Ferryside8
-rw-r--r--util/scan/dvb-t/uk-Guildford10
-rw-r--r--util/scan/dvb-t/uk-Hannington9
-rw-r--r--util/scan/dvb-t/uk-Hastings10
-rw-r--r--util/scan/dvb-t/uk-Heathfield10
-rw-r--r--util/scan/dvb-t/uk-HemelHempstead10
-rw-r--r--util/scan/dvb-t/uk-HuntshawCross13
-rw-r--r--util/scan/dvb-t/uk-Idle10
-rw-r--r--util/scan/dvb-t/uk-KeelylangHill10
-rw-r--r--util/scan/dvb-t/uk-Keighley10
-rw-r--r--util/scan/dvb-t/uk-KilveyHill10
-rw-r--r--util/scan/dvb-t/uk-KnockMore10
-rw-r--r--util/scan/dvb-t/uk-Lancaster10
-rw-r--r--util/scan/dvb-t/uk-LarkStoke10
-rw-r--r--util/scan/dvb-t/uk-Limavady10
-rw-r--r--util/scan/dvb-t/uk-Llanddona10
-rw-r--r--util/scan/dvb-t/uk-Malvern10
-rw-r--r--util/scan/dvb-t/uk-Mendip10
-rw-r--r--util/scan/dvb-t/uk-Midhurst10
-rw-r--r--util/scan/dvb-t/uk-Moel-y-Parc10
-rw-r--r--util/scan/dvb-t/uk-Nottingham10
-rw-r--r--util/scan/dvb-t/uk-OliversMount10
-rw-r--r--util/scan/dvb-t/uk-Oxford11
-rw-r--r--util/scan/dvb-t/uk-PendleForest10
-rw-r--r--util/scan/dvb-t/uk-Plympton10
-rw-r--r--util/scan/dvb-t/uk-PontopPike11
-rw-r--r--util/scan/dvb-t/uk-Pontypool10
-rw-r--r--util/scan/dvb-t/uk-Presely10
-rw-r--r--util/scan/dvb-t/uk-Redruth9
-rw-r--r--util/scan/dvb-t/uk-Reigate11
-rw-r--r--util/scan/dvb-t/uk-RidgeHill10
-rw-r--r--util/scan/dvb-t/uk-Rosemarkie10
-rw-r--r--util/scan/dvb-t/uk-Rosneath10
-rw-r--r--util/scan/dvb-t/uk-Rowridge11
-rw-r--r--util/scan/dvb-t/uk-RumsterForest10
-rw-r--r--util/scan/dvb-t/uk-Saddleworth10
-rw-r--r--util/scan/dvb-t/uk-Salisbury10
-rw-r--r--util/scan/dvb-t/uk-SandyHeath11
-rw-r--r--util/scan/dvb-t/uk-Selkirk10
-rw-r--r--util/scan/dvb-t/uk-Sheffield10
-rw-r--r--util/scan/dvb-t/uk-StocklandHill10
-rw-r--r--util/scan/dvb-t/uk-Storeton9
-rw-r--r--util/scan/dvb-t/uk-Sudbury12
-rw-r--r--util/scan/dvb-t/uk-SuttonColdfield10
-rw-r--r--util/scan/dvb-t/uk-Tacolneston10
-rw-r--r--util/scan/dvb-t/uk-TheWrekin15
-rw-r--r--util/scan/dvb-t/uk-Torosay10
-rw-r--r--util/scan/dvb-t/uk-TunbridgeWells10
-rw-r--r--util/scan/dvb-t/uk-Waltham10
-rw-r--r--util/scan/dvb-t/uk-Wenvoe10
-rw-r--r--util/scan/dvb-t/uk-WhitehawkHill10
-rw-r--r--util/scan/dvb-t/uk-WinterHill14
-rw-r--r--util/scan/list.h6
-rw-r--r--util/scan/lnb.c1
-rw-r--r--util/scan/lnb.h2
-rw-r--r--util/scan/scan.c66
-rw-r--r--util/scan/scan.h1
-rw-r--r--util/scan/section_generate.pl92
-rw-r--r--util/szap/Makefile39
-rw-r--r--util/szap/README23
-rw-r--r--util/szap/azap.c8
-rwxr-xr-xutil/szap/channels-conf/atsc/make_atsc_chanconf.pl110
-rw-r--r--util/szap/channels-conf/atsc/us-Raleigh-Durham8
-rw-r--r--util/szap/channels-conf/dvb-c/de-Berlin (renamed from util/szap/channels.conf-dvbc-berlin)10
-rw-r--r--util/szap/channels-conf/dvb-s/Astra-19.2E226
-rw-r--r--util/szap/channels-conf/dvb-s/Astra-28.2E522
-rw-r--r--util/szap/channels-conf/dvb-s/BrasilSat-B3-84.0W39
-rw-r--r--util/szap/channels-conf/dvb-t/au-Adelaide28
-rw-r--r--util/szap/channels-conf/dvb-t/au-Brisbane29
-rw-r--r--util/szap/channels-conf/dvb-t/au-Hobart18
-rw-r--r--util/szap/channels-conf/dvb-t/au-Melbourne17
-rw-r--r--util/szap/channels-conf/dvb-t/au-Sydney-NorthShore (renamed from util/szap/channels.conf-dvbt-australia)62
-rw-r--r--util/szap/channels-conf/dvb-t/cz-Praha16
-rw-r--r--util/szap/channels-conf/dvb-t/de-Berlin47
-rw-r--r--util/szap/channels-conf/dvb-t/de-Braunschweig25
-rw-r--r--util/szap/channels-conf/dvb-t/de-Bremen25
-rw-r--r--util/szap/channels-conf/dvb-t/de-Koeln-Bonn23
-rw-r--r--util/szap/channels-conf/dvb-t/de-Leipzig7
-rw-r--r--util/szap/channels-conf/dvb-t/de-Luebeck22
-rw-r--r--util/szap/channels-conf/dvb-t/de-Rhein-Main6
-rw-r--r--util/szap/channels-conf/dvb-t/de-Ruhrgebiet46
-rw-r--r--util/szap/channels-conf/dvb-t/es-Alpicat19
-rw-r--r--util/szap/channels-conf/dvb-t/es-Collserola (renamed from util/szap/channels.conf-dvbt-collserola)16
-rw-r--r--util/szap/channels-conf/dvb-t/es-Madrid26
-rw-r--r--util/szap/channels-conf/dvb-t/es-Mussara19
-rw-r--r--util/szap/channels-conf/dvb-t/uk-Crystal-Palace (renamed from util/szap/channels.conf-dvbt-crystal-palace)3
-rw-r--r--util/szap/channels-conf/dvb-t/uk-Hannington (renamed from util/szap/channels.conf-dvbt-hannington)0
-rw-r--r--util/szap/channels-conf/dvb-t/uk-Oxford (renamed from util/szap/channels.conf-dvbt-oxford)0
-rw-r--r--util/szap/channels-conf/dvb-t/uk-Reigate (renamed from util/szap/channels.conf-dvbt-reigate)0
-rw-r--r--util/szap/channels-conf/dvb-t/uk-Sandy-Heath (renamed from util/szap/channels.conf-dvbt-sandy_heath)1
-rw-r--r--util/szap/channels.conf-dvbs-astra226
-rw-r--r--util/szap/channels.conf-dvbt-berlin51
-rw-r--r--util/szap/channels.conf-dvbt-madrid16
-rw-r--r--util/szap/czap.c147
-rw-r--r--util/szap/femon.c149
-rw-r--r--util/szap/lnb.c101
-rw-r--r--util/szap/lnb.h22
-rw-r--r--util/szap/szap.c222
-rw-r--r--util/szap/tzap.c344
-rw-r--r--util/ttusb_dec_reset/Makefile28
-rw-r--r--util/ttusb_dec_reset/ttusb_dec_reset.c4
-rw-r--r--util/zap/Makefile20
-rw-r--r--util/zap/zap.c226
-rw-r--r--util/zap/zap_ca.c198
-rw-r--r--util/zap/zap_ca.h37
-rw-r--r--util/zap/zap_dvb.c353
-rw-r--r--util/zap/zap_dvb.h41
1282 files changed, 68297 insertions, 2474 deletions
diff --git a/.hg_archival.txt b/.hg_archival.txt
new file mode 100644
index 0000000..f91aca6
--- /dev/null
+++ b/.hg_archival.txt
@@ -0,0 +1,2 @@
+repo: d9fe7e17226f8e321aa80a015fc8d53f33b265d7
+node: 63dae165ffe8ae0e605fa46b77062289a873c0fb
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/COPYING.LGPL b/COPYING.LGPL
new file mode 100644
index 0000000..9c6a6cc
--- /dev/null
+++ b/COPYING.LGPL
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..27a11a0
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,26 @@
+Requirements:
+
+For ttusb_dec_reset, you will need libusb.
+
+Building:
+
+Simply type
+$ make
+
+Build options
+ static=1 - Build all applications statically.
+ V=1 - Verbose output during build.
+ ttusb_dec_reset=1 - Build the optional ttusb_dec_reset.
+
+Installing:
+
+Install libraries and utils to /usr/[bin,include,lib,share]
+$ make install
+
+Install options
+ prefix=<...> - basic installation dir [default: /usr]
+ bindir=<...> - installation dir for applications [default: $(prefix)/bin]
+ includedir=<...> - installation dir for include files [default: $(prefix)/include]
+ libdir=<...> - installation dir for applications [default: $(prefix)/lib]
+ sharedir=<...> - installation dir for shared data [default: $(prefix)/share]
+ DESTDIR=<...> - prefix for all files, useful for packaging
diff --git a/Make.rules b/Make.rules
new file mode 100644
index 0000000..e867c3a
--- /dev/null
+++ b/Make.rules
@@ -0,0 +1,104 @@
+# build rules for linuxtv.org dvb-apps
+
+CFLAGS ?= -g -Wall -W -Wshadow -Wpointer-arith -Wstrict-prototypes
+
+ifneq ($(lib_name),)
+
+# additional rules for libraries
+
+CFLAGS_LIB ?= -fPIC
+CFLAGS += $(CFLAGS_LIB)
+
+libraries = $(lib_name).so $(lib_name).a
+
+.PHONY: library
+
+library: $(libraries)
+
+$(libraries): $(objects)
+
+endif
+
+prerequisites = $(subst .o,.d,$(objects)) $(addsuffix .d,$(binaries))
+
+.PHONY: clean install
+
+ifeq ($(static),1)
+LDFLAGS += -static
+endif
+
+prefix ?= /usr
+
+bindir ?= $(prefix)/bin
+includedir ?= $(prefix)/include
+libdir ?= $(prefix)/lib
+sharedir ?= $(prefix)/share
+
+ifneq ($(DESTDIR),)
+DESTDIR = $(DESTDIR)/
+endif
+
+ifeq ($(V),1)
+%.o: %.c
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) -MMD -o $@ $< $(filter-out %.h %.c,$^)
+%: %.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS)
+%: %.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -MMD $(LDFLAGS) -o $@ $< $(filter-out %.h %.c,$^) $(LOADLIBES) $(LDLIBS)
+%.so:
+ $(CC) -shared -o $@ $^
+%.a:
+ $(AR) rcs $@ $^
+clean::
+ $(RM) -f $(prerequisites) $(objects) $(libraries) $(binaries) $(removing) *~
+install::
+ifneq ($(includes),)
+ mkdir -p $(DESTDIR)$(includedir)/$(lib_name)
+ install -m 644 $(includes) $(DESTDIR)$(includedir)/$(lib_name)/
+endif
+ifneq ($(libraries),)
+ mkdir -p $(DESTDIR)$(libdir)
+ install -m 644 $(libraries) $(DESTDIR)$(libdir)/
+endif
+ifneq ($(inst_bin),)
+ mkdir -p $(DESTDIR)$(bindir)
+ install -m 755 $(inst_bin) $(DESTDIR)$(bindir)/
+endif
+else
+%.o: %.c
+ @echo CC $@
+ @$(CC) -c $(CPPFLAGS) $(CFLAGS) -MMD -o $@ $< $(filter-out %.h %.c,$^)
+%: %.o
+ @echo CC $@
+ @$(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS)
+%: %.c
+ @echo CC $@
+ @$(CC) $(CPPFLAGS) $(CFLAGS) -MMD $(LDFLAGS) -o $@ $< $(filter-out %.h %.c,$^) $(LOADLIBES) $(LDLIBS)
+%.so:
+ @echo CC $@
+ @$(CC) -shared -o $@ $^
+%.a:
+ @echo AR $@
+ @$(AR) rcs $@ $^
+clean::
+ @echo cleaning
+ @$(RM) -f $(prerequisites) $(objects) $(libraries) $(binaries) $(removing) *~
+install::
+ifneq ($(includes),)
+ @echo installing headers
+ @mkdir -p $(DESTDIR)$(includedir)/$(lib_name)
+ @install -m 644 $(includes) $(DESTDIR)$(includedir)/$(lib_name)/
+endif
+ifneq ($(libraries),)
+ @echo installing libraries
+ @mkdir -p $(DESTDIR)$(libdir)
+ @install -m 644 $(libraries) $(DESTDIR)$(libdir)/
+endif
+ifneq ($(inst_bin),)
+ @echo installing binaries
+ @mkdir -p $(DESTDIR)$(bindir)
+ @install -m 755 $(inst_bin) $(DESTDIR)$(bindir)/
+endif
+endif
+
+-include $(prerequisites)
diff --git a/Makefile b/Makefile
index e0eadcf..0ca84b0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,28 +1,12 @@
# Makefile for linuxtv.org dvb-apps
-VERSION := 1.1.0
-PACKAGE := linuxtv-dvb-apps-$(VERSION)
-CVSROOT := $(shell cat CVS/Root)
-RELEASE_TAG := LINUXTV-DVB-$(subst .,_,$(subst -,_,$(VERSION)))
+.PHONY: all clean install update
-all:
+all clean install:
+ $(MAKE) -C lib $@
+ $(MAKE) -C test $@
+ $(MAKE) -C util $@
-release dist:
- rm -rf release-tmp $(PACKAGE).tar.gz
- mkdir release-tmp
- ( cd release-tmp; cvs -d$(CVSROOT) export -r$(RELEASE_TAG) -d$(PACKAGE) dvb-apps )
- find release-tmp -name .cvsignore | xargs rm -v
- ( cd release-tmp; tar cjf ../$(PACKAGE).tar.bz2 $(PACKAGE) )
- rm -rf release-tmp
- @echo
- @echo --------------------------------------------------------------------------------
- @echo
- @echo "dist package: ./$(PACKAGE).tar.bz2"
- @echo
- @echo --------------------------------------------------------------------------------
- @echo
-
-%::
-# $(MAKE) -C libdvb2 $(MAKECMDGOALS)
- $(MAKE) -C util $(MAKECMDGOALS)
- $(MAKE) -C test $(MAKECMDGOALS)
+update:
+ @echo "Pulling changes & updating from master repository"
+ hg pull -u
diff --git a/README b/README
index aced028..ad29647 100644
--- a/README
+++ b/README
@@ -1,28 +1,40 @@
-linuxtv-dvb-apps-1.1.1
+linuxtv-dvb-apps-1.?
======================
-Linux DVB API test/demo applications and utilities.
+Linux DVB API applications and utilities.
-You find a README in each subdirectory explaining what the code there does.
-For beginners utils/szap/ and utils/scan/ are probably most useful.
+All applications support the DVB-S, DVB-C, DVB-T, and ATSC standards.
-For convenience, dvb-apps contains a copy of the DVB API include
-files as they are contained in the linuxtv-dvb-1.1.0 realease
-and the 2.6.x Linux kernel. However, since the DVB API hasn't changed,
-the apps will still work with the old "DVB" drivers, should you decide not
-to use linuxtv-dvb-1.1.0 (or the dvb-kernel CVS).
+Main User Applications:
+util/scan - Scan for channels on your digital TV device.
+util/gnutv - Tune, watch and stream your TV.
+General Utilities:
+util/dvbdate - Set your clock from digital TV.
+util/dvbnet - Control digital data network interfaces.
+util/dvbtraffic - Monitor traffic on a digital device.
+util/femon - Monitor the tuning on a digital TV device.
+util/zap - *Just* tunes a digital device - really intended for developers.
-Historical note:
-The apps have been copied from the "DVB" CVS tree, which means that
-the stuff in "DVB" is now unmaintained and out of date.
+Hardware Specific Utilities:
+util/av7110_loadkeys - Load remote keys into an av7110 based card
+util/dib3000-watch - Monitor DIB3000 demodulators
+util/dst-utils - Utilities for DST based cards.
+util/ttusb_dec_reset - Reset a TechnoTrends TTUSB DEC device.
+Libraries:
+lib/libdvbapi - Interface library to digital TV devices.
+lib/libdvbcfg - Library to parse/create digital TV channel configuration files.
+lib/libdvbsec - Library for Satellite Equipment Control operations.
+lib/libucsi - Fast MPEG2 Transport Stream SI table parsing library.
+lib/libdvben50221- Complete implementation of a Cenelec EN 50221 CAM stack.
+lib/libdvbmisc - Miscellaneous utilities used by the other libraries.
-Johannes Stezenbach <js@convergence.de>
+Various testing applications also live in test.
-This is an interim point release adding support for ATSC to the 1.1.0 release.
-dvb-apps is currently being rewritten completely with new standardised DVB
-libraries for all aspects of DVB, ca support etc, so expect a 1.2.0 release
-at some point soon.
+For convenience, dvb-apps contains a copy of the DVB API include
+files as they are contained in the linuxtv-dvb-1.? release
+and the 2.6.x Linux kernel.
+Johannes Stezenbach <js@convergence.de>
Andrew de Quincey <adq_dvb@lidskialf.net>
diff --git a/TODO b/TODO
deleted file mode 100644
index 416b66f..0000000
--- a/TODO
+++ /dev/null
@@ -1 +0,0 @@
-- create libdvb2, possibly merging util/lib/*
diff --git a/include/linux/dvb/audio.h b/include/audio.h
index 58956c3..89412e1 100644
--- a/include/linux/dvb/audio.h
+++ b/include/audio.h
@@ -1,9 +1,9 @@
-/*
+/*
* audio.h
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
- for convergence integrated media GmbH
+ * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public License
@@ -32,39 +32,41 @@
typedef enum {
- AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */
- AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */
+ AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */
+ AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */
} audio_stream_source_t;
-typedef enum {
- AUDIO_STOPPED, /* Device is stopped */
- AUDIO_PLAYING, /* Device is currently playing */
- AUDIO_PAUSED /* Device is paused */
+typedef enum {
+ AUDIO_STOPPED, /* Device is stopped */
+ AUDIO_PLAYING, /* Device is currently playing */
+ AUDIO_PAUSED /* Device is paused */
} audio_play_state_t;
typedef enum {
- AUDIO_STEREO,
- AUDIO_MONO_LEFT,
- AUDIO_MONO_RIGHT
+ AUDIO_STEREO,
+ AUDIO_MONO_LEFT,
+ AUDIO_MONO_RIGHT,
+ AUDIO_MONO,
+ AUDIO_STEREO_SWAPPED
} audio_channel_select_t;
-typedef struct audio_mixer {
- unsigned int volume_left;
- unsigned int volume_right;
+typedef struct audio_mixer {
+ unsigned int volume_left;
+ unsigned int volume_right;
// what else do we need? bass, pass-through, ...
} audio_mixer_t;
-typedef struct audio_status {
- int AV_sync_state; /* sync audio and video? */
- int mute_state; /* audio is muted */
- audio_play_state_t play_state; /* current playback state */
- audio_stream_source_t stream_source; /* current stream source */
- audio_channel_select_t channel_select; /* currently selected channel */
- int bypass_mode; /* pass on audio data to */
+typedef struct audio_status {
+ int AV_sync_state; /* sync audio and video? */
+ int mute_state; /* audio is muted */
+ audio_play_state_t play_state; /* current playback state */
+ audio_stream_source_t stream_source; /* current stream source */
+ audio_channel_select_t channel_select; /* currently selected channel */
+ int bypass_mode; /* pass on audio data to */
audio_mixer_t mixer_state; /* current mixer state */
} audio_status_t; /* separate decoder hardware */
@@ -74,8 +76,8 @@ struct audio_karaoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */
int vocal1; /* into left and right t at 70% each */
int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets*/
int melody; /* mixed into the left channel and */
- /* Vocal2 into the right channel at 100% each. */
- /* if Melody is non-zero, the melody channel gets mixed*/
+ /* Vocal2 into the right channel at 100% each. */
+ /* if Melody is non-zero, the melody channel gets mixed*/
} audio_karaoke_t; /* into left and right */
@@ -88,7 +90,7 @@ typedef uint16_t audio_attributes_t;
/* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */
/* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */
/* 2- 0 number of audio channels (n+1 channels) */
-
+
/* for GET_CAPABILITIES and SET_FORMAT, the latter should only set one bit */
#define AUDIO_CAP_DTS 1
@@ -101,7 +103,7 @@ typedef uint16_t audio_attributes_t;
#define AUDIO_CAP_SDDS 128
#define AUDIO_CAP_AC3 256
-#define AUDIO_STOP _IO('o', 1)
+#define AUDIO_STOP _IO('o', 1)
#define AUDIO_PLAY _IO('o', 2)
#define AUDIO_PAUSE _IO('o', 3)
#define AUDIO_CONTINUE _IO('o', 4)
@@ -121,5 +123,18 @@ typedef uint16_t audio_attributes_t;
#define AUDIO_SET_ATTRIBUTES _IOW('o', 17, audio_attributes_t)
#define AUDIO_SET_KARAOKE _IOW('o', 18, audio_karaoke_t)
-#endif /* _DVBAUDIO_H_ */
+/**
+ * AUDIO_GET_PTS
+ *
+ * Read the 33 bit presentation time stamp as defined
+ * in ITU T-REC-H.222.0 / ISO/IEC 13818-1.
+ *
+ * The PTS should belong to the currently played
+ * frame if possible, but may also be a value close to it
+ * like the PTS of the last decoded frame or the last PTS
+ * extracted by the PES parser.
+ */
+#define AUDIO_GET_PTS _IOR('o', 19, __u64)
+#define AUDIO_BILINGUAL_CHANNEL_SELECT _IO('o', 20)
+#endif /* _DVBAUDIO_H_ */
diff --git a/include/linux/dvb/ca.h b/include/ca.h
index 026e5c3..c18537f 100644
--- a/include/linux/dvb/ca.h
+++ b/include/ca.h
@@ -1,9 +1,9 @@
-/*
+/*
* ca.h
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
- for convergence integrated media GmbH
+ * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public License
@@ -27,16 +27,16 @@
/* slot interface types and info */
typedef struct ca_slot_info {
- int num; /* slot number */
+ int num; /* slot number */
- int type; /* CA interface this slot supports */
+ int type; /* CA interface this slot supports */
#define CA_CI 1 /* CI high level interface */
#define CA_CI_LINK 2 /* CI link layer level interface */
#define CA_CI_PHYS 4 /* CI physical layer level interface */
#define CA_DESCR 8 /* built-in descrambler */
#define CA_SC 128 /* simple smart card interface */
- unsigned int flags;
+ unsigned int flags;
#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
#define CA_CI_MODULE_READY 2
} ca_slot_info_t;
@@ -45,37 +45,37 @@ typedef struct ca_slot_info {
/* descrambler types and info */
typedef struct ca_descr_info {
- unsigned int num; /* number of available descramblers (keys) */
- unsigned int type; /* type of supported scrambling system */
+ unsigned int num; /* number of available descramblers (keys) */
+ unsigned int type; /* type of supported scrambling system */
#define CA_ECD 1
#define CA_NDS 2
#define CA_DSS 4
} ca_descr_info_t;
typedef struct ca_caps {
- unsigned int slot_num; /* total number of CA card and module slots */
- unsigned int slot_type; /* OR of all supported types */
- unsigned int descr_num; /* total number of descrambler slots (keys) */
- unsigned int descr_type; /* OR of all supported types */
+ unsigned int slot_num; /* total number of CA card and module slots */
+ unsigned int slot_type; /* OR of all supported types */
+ unsigned int descr_num; /* total number of descrambler slots (keys) */
+ unsigned int descr_type; /* OR of all supported types */
} ca_caps_t;
/* a message to/from a CI-CAM */
typedef struct ca_msg {
- unsigned int index;
- unsigned int type;
- unsigned int length;
- unsigned char msg[256];
+ unsigned int index;
+ unsigned int type;
+ unsigned int length;
+ unsigned char msg[256];
} ca_msg_t;
typedef struct ca_descr {
- unsigned int index;
- unsigned int parity; /* 0 == even, 1 == odd */
- unsigned char cw[8];
+ unsigned int index;
+ unsigned int parity; /* 0 == even, 1 == odd */
+ unsigned char cw[8];
} ca_descr_t;
typedef struct ca_pid {
- unsigned int pid;
- int index; /* -1 == disable*/
+ unsigned int pid;
+ int index; /* -1 == disable*/
} ca_pid_t;
#define CA_RESET _IO('o', 128)
@@ -88,4 +88,3 @@ typedef struct ca_pid {
#define CA_SET_PID _IOW('o', 135, ca_pid_t)
#endif
-
diff --git a/include/linux/dvb/dmx.h b/include/dmx.h
index 62e6217..c6a2353 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/dmx.h
@@ -1,9 +1,9 @@
-/*
+/*
* dmx.h
*
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de>
- for convergence integrated media GmbH
+ * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -38,10 +38,10 @@ typedef enum
{
DMX_OUT_DECODER, /* Streaming directly to decoder. */
DMX_OUT_TAP, /* Output going to a memory buffer */
- /* (to be retrieved via the read command).*/
+ /* (to be retrieved via the read command).*/
DMX_OUT_TS_TAP /* Output multiplexed into a new TS */
- /* (to be retrieved by reading from the */
- /* logical DVR device). */
+ /* (to be retrieved by reading from the */
+ /* logical DVR device). */
} dmx_output_t;
@@ -54,25 +54,25 @@ typedef enum
typedef enum
{
- DMX_PES_AUDIO0,
+ DMX_PES_AUDIO0,
DMX_PES_VIDEO0,
DMX_PES_TELETEXT0,
DMX_PES_SUBTITLE0,
DMX_PES_PCR0,
- DMX_PES_AUDIO1,
+ DMX_PES_AUDIO1,
DMX_PES_VIDEO1,
DMX_PES_TELETEXT1,
DMX_PES_SUBTITLE1,
DMX_PES_PCR1,
- DMX_PES_AUDIO2,
+ DMX_PES_AUDIO2,
DMX_PES_VIDEO2,
DMX_PES_TELETEXT2,
DMX_PES_SUBTITLE2,
DMX_PES_PCR2,
- DMX_PES_AUDIO3,
+ DMX_PES_AUDIO3,
DMX_PES_VIDEO3,
DMX_PES_TELETEXT3,
DMX_PES_SUBTITLE3,
@@ -88,20 +88,6 @@ typedef enum
#define DMX_PES_PCR DMX_PES_PCR0
-typedef enum
-{
- DMX_SCRAMBLING_EV,
- DMX_FRONTEND_EV
-} dmx_event_t;
-
-
-typedef enum
-{
- DMX_SCRAMBLING_OFF,
- DMX_SCRAMBLING_ON
-} dmx_scrambling_status_t;
-
-
typedef struct dmx_filter
{
__u8 filter[DMX_FILTER_SIZE];
@@ -112,10 +98,10 @@ typedef struct dmx_filter
struct dmx_sct_filter_params
{
- __u16 pid;
+ __u16 pid;
dmx_filter_t filter;
- __u32 timeout;
- __u32 flags;
+ __u32 timeout;
+ __u32 flags;
#define DMX_CHECK_CRC 1
#define DMX_ONESHOT 2
#define DMX_IMMEDIATE_START 4
@@ -125,27 +111,16 @@ struct dmx_sct_filter_params
struct dmx_pes_filter_params
{
- __u16 pid;
+ __u16 pid;
dmx_input_t input;
dmx_output_t output;
dmx_pes_type_t pes_type;
- __u32 flags;
-};
-
-
-struct dmx_event
-{
- dmx_event_t event;
- time_t timeStamp;
- union
- {
- dmx_scrambling_status_t scrambling;
- } u;
+ __u32 flags;
};
typedef struct dmx_caps {
__u32 caps;
- int num_decoders;
+ int num_decoders;
} dmx_caps_t;
typedef enum {
@@ -166,16 +141,14 @@ struct dmx_stc {
};
-#define DMX_START _IO('o', 41)
+#define DMX_START _IO('o', 41)
#define DMX_STOP _IO('o', 42)
#define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params)
#define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params)
#define DMX_SET_BUFFER_SIZE _IO('o', 45)
-#define DMX_GET_EVENT _IOR('o', 46, struct dmx_event)
#define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5])
#define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t)
#define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t)
#define DMX_GET_STC _IOWR('o', 50, struct dmx_stc)
#endif /*_DVBDMX_H_*/
-
diff --git a/include/frontend.h b/include/frontend.h
new file mode 100644
index 0000000..71abc24
--- /dev/null
+++ b/include/frontend.h
@@ -0,0 +1,648 @@
+/*
+ * frontend.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ * Ralph Metzler <ralph@convergence.de>
+ * Holger Waechtler <holger@convergence.de>
+ * Andre Draszik <ad@convergence.de>
+ * for convergence integrated media GmbH
+ *
+ * Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _DVBFRONTEND_H_
+#define _DVBFRONTEND_H_
+
+#include <asm/types.h>
+
+
+typedef enum fe_type {
+ FE_QPSK,
+ FE_QAM,
+ FE_OFDM,
+ FE_ATSC
+} fe_type_t;
+
+
+typedef enum fe_caps {
+ FE_IS_STUPID = 0,
+ FE_CAN_INVERSION_AUTO = 0x1,
+ FE_CAN_FEC_1_2 = 0x2,
+ FE_CAN_FEC_2_3 = 0x4,
+ FE_CAN_FEC_3_4 = 0x8,
+ FE_CAN_FEC_4_5 = 0x10,
+ FE_CAN_FEC_5_6 = 0x20,
+ FE_CAN_FEC_6_7 = 0x40,
+ FE_CAN_FEC_7_8 = 0x80,
+ FE_CAN_FEC_8_9 = 0x100,
+ FE_CAN_FEC_AUTO = 0x200,
+ FE_CAN_QPSK = 0x400,
+ FE_CAN_QAM_16 = 0x800,
+ FE_CAN_QAM_32 = 0x1000,
+ FE_CAN_QAM_64 = 0x2000,
+ FE_CAN_QAM_128 = 0x4000,
+ FE_CAN_QAM_256 = 0x8000,
+ FE_CAN_QAM_AUTO = 0x10000,
+ FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
+ FE_CAN_BANDWIDTH_AUTO = 0x40000,
+ FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
+ FE_CAN_HIERARCHY_AUTO = 0x100000,
+ FE_CAN_8VSB = 0x200000,
+ FE_CAN_16VSB = 0x400000,
+ FE_NEEDS_BENDING = 0x20000000, // not supported anymore, don't use (frontend requires frequency bending)
+ FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically
+ FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output
+} fe_caps_t;
+
+
+struct dvb_frontend_info {
+ char name[128];
+ fe_type_t type;
+ __u32 frequency_min;
+ __u32 frequency_max;
+ __u32 frequency_stepsize;
+ __u32 frequency_tolerance;
+ __u32 symbol_rate_min;
+ __u32 symbol_rate_max;
+ __u32 symbol_rate_tolerance; /* ppm */
+ __u32 notifier_delay; /* DEPRECATED */
+ fe_caps_t caps;
+};
+
+
+/**
+ * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
+ * the meaning of this struct...
+ */
+struct dvb_diseqc_master_cmd {
+ __u8 msg [6]; /* { framing, address, command, data [3] } */
+ __u8 msg_len; /* valid values are 3...6 */
+};
+
+
+struct dvb_diseqc_slave_reply {
+ __u8 msg [4]; /* { framing, data [3] } */
+ __u8 msg_len; /* valid values are 0...4, 0 means no msg */
+ int timeout; /* return from ioctl after timeout ms with */
+}; /* errorcode when no message was received */
+
+
+typedef enum fe_sec_voltage {
+ SEC_VOLTAGE_13,
+ SEC_VOLTAGE_18,
+ SEC_VOLTAGE_OFF
+} fe_sec_voltage_t;
+
+
+typedef enum fe_sec_tone_mode {
+ SEC_TONE_ON,
+ SEC_TONE_OFF
+} fe_sec_tone_mode_t;
+
+
+typedef enum fe_sec_mini_cmd {
+ SEC_MINI_A,
+ SEC_MINI_B
+} fe_sec_mini_cmd_t;
+
+
+typedef enum fe_status {
+ FE_HAS_SIGNAL = 0x01, /* found something above the noise level */
+ FE_HAS_CARRIER = 0x02, /* found a DVB signal */
+ FE_HAS_VITERBI = 0x04, /* FEC is stable */
+ FE_HAS_SYNC = 0x08, /* found sync bytes */
+ FE_HAS_LOCK = 0x10, /* everything's working... */
+ FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */
+ FE_REINIT = 0x40 /* frontend was reinitialized, */
+} fe_status_t; /* application is recommended to reset */
+ /* DiSEqC, tone and parameters */
+
+typedef enum fe_spectral_inversion {
+ INVERSION_OFF,
+ INVERSION_ON,
+ INVERSION_AUTO
+} fe_spectral_inversion_t;
+
+
+typedef enum fe_code_rate {
+ FEC_NONE = 0,
+ FEC_1_2,
+ FEC_2_3,
+ FEC_3_4,
+ FEC_4_5,
+ FEC_5_6,
+ FEC_6_7,
+ FEC_7_8,
+ FEC_8_9,
+ FEC_AUTO
+} fe_code_rate_t;
+
+
+typedef enum fe_modulation {
+ QPSK,
+ QAM_16,
+ QAM_32,
+ QAM_64,
+ QAM_128,
+ QAM_256,
+ QAM_AUTO,
+ VSB_8,
+ VSB_16
+} fe_modulation_t;
+
+typedef enum fe_transmit_mode {
+ TRANSMISSION_MODE_2K,
+ TRANSMISSION_MODE_8K,
+ TRANSMISSION_MODE_AUTO
+} fe_transmit_mode_t;
+
+typedef enum fe_bandwidth {
+ BANDWIDTH_8_MHZ,
+ BANDWIDTH_7_MHZ,
+ BANDWIDTH_6_MHZ,
+ BANDWIDTH_AUTO
+} fe_bandwidth_t;
+
+
+typedef enum fe_guard_interval {
+ GUARD_INTERVAL_1_32,
+ GUARD_INTERVAL_1_16,
+ GUARD_INTERVAL_1_8,
+ GUARD_INTERVAL_1_4,
+ GUARD_INTERVAL_AUTO
+} fe_guard_interval_t;
+
+
+typedef enum fe_hierarchy {
+ HIERARCHY_NONE,
+ HIERARCHY_1,
+ HIERARCHY_2,
+ HIERARCHY_4,
+ HIERARCHY_AUTO
+} fe_hierarchy_t;
+
+
+struct dvb_qpsk_parameters {
+ __u32 symbol_rate; /* symbol rate in Symbols per second */
+ fe_code_rate_t fec_inner; /* forward error correction (see above) */
+};
+
+struct dvb_qam_parameters {
+ __u32 symbol_rate; /* symbol rate in Symbols per second */
+ fe_code_rate_t fec_inner; /* forward error correction (see above) */
+ fe_modulation_t modulation; /* modulation type (see above) */
+};
+
+struct dvb_vsb_parameters {
+ fe_modulation_t modulation; /* modulation type (see above) */
+};
+
+struct dvb_ofdm_parameters {
+ fe_bandwidth_t bandwidth;
+ fe_code_rate_t code_rate_HP; /* high priority stream code rate */
+ fe_code_rate_t code_rate_LP; /* low priority stream code rate */
+ fe_modulation_t constellation; /* modulation type (see above) */
+ fe_transmit_mode_t transmission_mode;
+ fe_guard_interval_t guard_interval;
+ fe_hierarchy_t hierarchy_information;
+};
+
+
+struct dvb_frontend_parameters {
+ __u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
+ /* intermediate frequency in kHz for QPSK */
+ fe_spectral_inversion_t inversion;
+ union {
+ struct dvb_qpsk_parameters qpsk;
+ struct dvb_qam_parameters qam;
+ struct dvb_ofdm_parameters ofdm;
+ struct dvb_vsb_parameters vsb;
+ } u;
+};
+
+
+/**
+ * When set, this flag will disable any zigzagging or other "normal" tuning
+ * behaviour. Additionally, there will be no automatic monitoring of the lock
+ * status, and hence no frontend events will be generated. If a frontend device
+ * is closed, this flag will be automatically turned off when the device is
+ * reopened read-write.
+ */
+#define FE_TUNE_MODE_ONESHOT 0x01
+
+
+#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
+
+#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
+#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
+#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
+#define FE_DISEQC_SEND_BURST _IO('o', 65) /* fe_sec_mini_cmd_t */
+
+#define FE_SET_TONE _IO('o', 66) /* fe_sec_tone_mode_t */
+#define FE_SET_VOLTAGE _IO('o', 67) /* fe_sec_voltage_t */
+#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */
+
+#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
+#define FE_READ_BER _IOR('o', 70, __u32)
+#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
+#define FE_READ_SNR _IOR('o', 72, __u16)
+#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
+
+#define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters)
+#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
+#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */
+
+#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
+
+/*
+ * References:
+ * DVB-S : EN 300 421
+ * DVB-S2: EN 302 307, TR 102 376, EN 301 210
+ * DVB-C : EN 300 429
+ * DVB-T : EN 300 744
+ * DVB-H : EN 300 304
+ * ATSC : A/53A
+ */
+
+/*
+ * Delivery Systems
+ * needs to set/queried for multistandard frontends
+ */
+enum dvbfe_delsys {
+ DVBFE_DELSYS_DVBS = (1 << 0),
+ DVBFE_DELSYS_DSS = (1 << 1),
+ DVBFE_DELSYS_DVBS2 = (1 << 2),
+ DVBFE_DELSYS_DVBC = (1 << 3),
+ DVBFE_DELSYS_DVBT = (1 << 4),
+ DVBFE_DELSYS_DVBH = (1 << 5),
+ DVBFE_DELSYS_ATSC = (1 << 6),
+ DVBFE_DELSYS_DUMMY = (1 << 31)
+};
+#define DVBFE_GET_DELSYS _IOR('o', 82, enum dvbfe_delsys)
+#define DVBFE_SET_DELSYS _IOW('o', 87, enum dvbfe_delsys)
+
+/* Modulation types */
+enum dvbfe_modulation {
+ DVBFE_MOD_NONE = (0 << 0),
+ DVBFE_MOD_BPSK = (1 << 0),
+ DVBFE_MOD_QPSK = (1 << 1),
+ DVBFE_MOD_OQPSK = (1 << 2),
+ DVBFE_MOD_8PSK = (1 << 3),
+ DVBFE_MOD_16APSK = (1 << 4),
+ DVBFE_MOD_32APSK = (1 << 5),
+ DVBFE_MOD_QAM4 = (1 << 6),
+ DVBFE_MOD_QAM16 = (1 << 7),
+ DVBFE_MOD_QAM32 = (1 << 8),
+ DVBFE_MOD_QAM64 = (1 << 9),
+ DVBFE_MOD_QAM128 = (1 << 10),
+ DVBFE_MOD_QAM256 = (1 << 11),
+ DVBFE_MOD_QAM512 = (1 << 12),
+ DVBFE_MOD_QAM1024 = (1 << 13),
+ DVBFE_MOD_QAMAUTO = (1 << 14),
+ DVBFE_MOD_OFDM = (1 << 15),
+ DVBFE_MOD_COFDM = (1 << 16),
+ DVBFE_MOD_VSB8 = (1 << 17),
+ DVBFE_MOD_VSB16 = (1 << 18),
+ DVBFE_MOD_AUTO = (1 << 31)
+};
+
+/*
+ * Convolution Code Rate (Viterbi Inner Code Rate)
+ * DVB-S2 uses LDPC. Information on LDPC can be found at
+ * http://www.ldpc-codes.com
+ */
+enum dvbfe_fec {
+ DVBFE_FEC_NONE = (0 << 0),
+ DVBFE_FEC_1_4 = (1 << 0),
+ DVBFE_FEC_1_3 = (1 << 1),
+ DVBFE_FEC_2_5 = (1 << 2),
+ DVBFE_FEC_1_2 = (1 << 3),
+ DVBFE_FEC_3_5 = (1 << 4),
+ DVBFE_FEC_2_3 = (1 << 5),
+ DVBFE_FEC_3_4 = (1 << 6),
+ DVBFE_FEC_4_5 = (1 << 7),
+ DVBFE_FEC_5_6 = (1 << 8),
+ DVBFE_FEC_6_7 = (1 << 9),
+ DVBFE_FEC_7_8 = (1 << 10),
+ DVBFE_FEC_8_9 = (1 << 11),
+ DVBFE_FEC_9_10 = (1 << 12),
+ DVBFE_FEC_AUTO = (1 << 31)
+};
+
+/* Frontend Inversion (I/Q Swap) */
+enum dvbfe_inversion {
+ DVBFE_INVERSION_OFF = 0,
+ DVBFE_INVERSION_ON = 1,
+ DVBFE_INVERSION_AUTO = 2
+};
+
+/* DVB-S parameters */
+struct dvbs_params {
+ __u32 symbol_rate;
+
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/* DSS parameters */
+struct dss_params {
+ __u32 symbol_rate;
+
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/*
+ * Rolloff Rate (Nyquist Filter Rolloff)
+ * NOTE: DVB-S2 has rates of 0.20, 0.25, 0.35
+ * Values are x100
+ * Applies to DVB-S2
+ */
+enum dvbfe_rolloff {
+ DVBFE_ROLLOFF_35 = 0,
+ DVBFE_ROLLOFF_25 = 1,
+ DVBFE_ROLLOFF_20 = 2,
+ DVBFE_ROLLOFF_UNKNOWN = 3
+};
+
+/* DVB-S2 parameters */
+struct dvbs2_params {
+ __u32 symbol_rate;
+
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+
+ /* Informational fields only */
+ enum dvbfe_rolloff rolloff;
+
+ __u8 matype_1;
+ __u8 matype_2;
+ __u8 upl_1;
+ __u8 upl_2;
+ __u8 dfl_1;
+ __u8 dfl_2;
+ __u8 sync;
+ __u8 syncd_1;
+ __u8 syncd_2;
+
+ __u8 pad[32];
+};
+
+/* DVB-C parameters */
+struct dvbc_params {
+ __u32 symbol_rate;
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/* DVB-T Channel bandwidth */
+enum dvbfe_bandwidth {
+ DVBFE_BANDWIDTH_8_MHZ = (1 << 0),
+ DVBFE_BANDWIDTH_7_MHZ = (1 << 1),
+ DVBFE_BANDWIDTH_6_MHZ = (1 << 2),
+ DVBFE_BANDWIDTH_5_MHZ = (1 << 3),
+ DVBFE_BANDWIDTH_AUTO = (1 << 31)
+};
+
+/* DVB-T/DVB-H transmission mode */
+enum dvbfe_transmission_mode {
+ DVBFE_TRANSMISSION_MODE_2K = (1 << 0),
+ DVBFE_TRANSMISSION_MODE_4K = (1 << 1),
+ DVBFE_TRANSMISSION_MODE_8K = (1 << 2),
+ DVBFE_TRANSMISSION_MODE_AUTO = (1 << 31)
+};
+
+/* DVB-T/DVB-H Guard interval */
+enum dvbfe_guard_interval {
+ DVBFE_GUARD_INTERVAL_1_32 = (1 << 1),
+ DVBFE_GUARD_INTERVAL_1_16 = (1 << 2),
+ DVBFE_GUARD_INTERVAL_1_8 = (1 << 3),
+ DVBFE_GUARD_INTERVAL_1_4 = (1 << 4),
+ DVBFE_GUARD_INTERVAL_AUTO = (1 << 31)
+};
+
+/* DVB-T/DVB-H Hierarchial modulation */
+enum dvbfe_hierarchy {
+ DVBFE_HIERARCHY_OFF = (1 << 0),
+ DVBFE_HIERARCHY_ON = (1 << 1),
+ DVBFE_HIERARCHY_AUTO = (1 << 2)
+};
+
+/* DVB-T/DVB-H Rolloff's */
+enum dvbfe_alpha {
+ DVBFE_ALPHA_1 = (1 << 0),
+ DVBFE_ALPHA_2 = (1 << 1),
+ DVBFE_ALPHA_4 = (1 << 2)
+};
+
+/* Stream priority (Hierachial coding) */
+enum dvbfe_stream_priority {
+ DVBFE_STREAM_PRIORITY_HP = (0 << 0),
+ DVBFE_STREAM_PRIORITY_LP = (1 << 0)
+};
+
+/* DVB-T parameters */
+struct dvbt_params {
+ enum dvbfe_modulation constellation;
+ enum dvbfe_bandwidth bandwidth;
+ enum dvbfe_fec code_rate_HP;
+ enum dvbfe_fec code_rate_LP;
+ enum dvbfe_transmission_mode transmission_mode;
+ enum dvbfe_guard_interval guard_interval;
+ enum dvbfe_hierarchy hierarchy;
+ enum dvbfe_alpha alpha;
+ enum dvbfe_stream_priority priority;
+
+ __u8 pad[32];
+};
+
+/* DVB-H Interleaver type */
+enum dvbfe_interleaver {
+ DVBFE_INTERLEAVER_NATIVE = (1 << 0),
+ DVBFE_INTERLEAVER_INDEPTH = (1 << 1),
+ DVBFE_INTERLEAVER_AUTO = (1 << 31)
+};
+
+/* DVB-H MPE-FEC Indicator */
+enum dvbfe_mpefec {
+ DVBFE_MPEFEC_OFF = (1 << 0),
+ DVBFE_MPEFEC_ON = (1 << 1)
+};
+
+/* DVB-H Timeslicing Indicator */
+enum dvbfe_timeslicing {
+ DVBFE_TIMESLICING_OFF = (1 << 0),
+ DVBFE_TIMESLICING_ON = (1 << 1)
+};
+
+/* DVB-H parameters */
+struct dvbh_params {
+ enum dvbfe_modulation constellation;
+ enum dvbfe_fec code_rate_HP;
+ enum dvbfe_fec code_rate_LP;
+ enum dvbfe_transmission_mode transmission_mode;
+ enum dvbfe_guard_interval guard_interval;
+ enum dvbfe_hierarchy hierarchy;
+ enum dvbfe_alpha alpha;
+ enum dvbfe_interleaver interleaver;
+ enum dvbfe_mpefec mpefec;
+ enum dvbfe_timeslicing timeslicing;
+ enum dvbfe_stream_priority priority;
+
+ __u32 bandwidth;
+ __u8 pad[32];
+};
+
+/* ATSC parameters */
+struct atsc_params {
+ enum dvbfe_modulation modulation;
+
+ __u8 pad[32];
+};
+
+/* DVB Frontend Tuning Parameters */
+struct dvbfe_params {
+ __u32 frequency;
+ enum fe_spectral_inversion inversion;
+ enum dvbfe_delsys delivery;
+
+ __u8 pad[32];
+
+ union {
+ struct dvbs_params dvbs;
+ struct dss_params dss;
+ struct dvbs2_params dvbs2;
+ struct dvbc_params dvbc;
+ struct dvbt_params dvbt;
+ struct dvbh_params dvbh;
+ struct atsc_params atsc;
+
+ __u8 pad[128];
+ } delsys;
+};
+#define DVBFE_SET_PARAMS _IOW('o', 83, struct dvbfe_params)
+#define DVBFE_GET_PARAMS _IOWR('o', 84, struct dvbfe_params)
+
+/* DVB-S capability bitfields */
+struct dvbfe_dvbs_info {
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/* DSS capability bitfields */
+struct dvbfe_dss_info {
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/* DVB-S2 capability bitfields */
+struct dvbfe_dvbs2_info {
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+
+ __u8 pad[32];
+};
+
+/* DVB-C capability bitfields */
+struct dvbfe_dvbc_info {
+ enum dvbfe_modulation modulation;
+};
+
+/* DVB-T capability bitfields */
+struct dvbfe_dvbt_info {
+ enum dvbfe_modulation modulation;
+ enum dvbfe_stream_priority stream_priority;
+
+ __u8 pad[32];
+};
+
+/* DVB-H capability bitfields */
+struct dvbfe_dvbh_info {
+ enum dvbfe_modulation modulation;
+ enum dvbfe_stream_priority stream_priority;
+
+ __u8 pad[32];
+};
+
+/* ATSC capability bitfields */
+struct dvbfe_atsc_info {
+ enum dvbfe_modulation modulation;
+
+ __u8 pad[32];
+};
+
+/* DVB Frontend related Information */
+struct dvbfe_info {
+ char name[128];
+
+ union {
+ struct dvbfe_dvbs_info dvbs;
+ struct dvbfe_dss_info dss;
+ struct dvbfe_dvbs2_info dvbs2;
+ struct dvbfe_dvbc_info dvbc;
+ struct dvbfe_dvbt_info dvbt;
+ struct dvbfe_dvbh_info dvbh;
+ struct dvbfe_atsc_info atsc;
+
+ __u8 pad[128];
+ } delsys;
+
+ __u32 frequency_min;
+ __u32 frequency_max;
+ __u32 frequency_step;
+ __u32 frequency_tolerance;
+ __u32 symbol_rate_min;
+ __u32 symbol_rate_max;
+ __u32 symbol_rate_tolerance;
+
+ enum fe_spectral_inversion inversion;
+
+ __u8 pad[128];
+};
+#define DVBFE_GET_INFO _IOR('o', 85, struct dvbfe_info)
+
+enum dvbfe_status {
+ DVBFE_HAS_SIGNAL = (1 << 0), /* something above noise floor */
+ DVBFE_HAS_CARRIER = (1 << 1), /* Signal found */
+ DVBFE_HAS_VITERBI = (1 << 2), /* FEC is stable */
+ DVBFE_HAS_SYNC = (1 << 3), /* SYNC found */
+ DVBFE_HAS_LOCK = (1 << 4), /* OK .. */
+ DVBFE_TIMEDOUT = (1 << 5), /* no lock in last ~2 s */
+ DVBFE_STATUS_DUMMY = (1 << 31)
+};
+
+/* DVB Frontend events */
+struct dvbfe_events {
+ enum dvbfe_status status;
+
+ __u8 pad[32];
+};
+
+struct dvb_frontend_event {
+ fe_status_t status;
+ struct dvb_frontend_parameters parameters;
+};
+#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
+
+struct dvbfe_event {
+ struct dvbfe_events fe_events;
+ struct dvbfe_params fe_params;
+};
+#define DVBFE_GET_EVENT _IOR('o', 86, struct dvbfe_event)
+
+#endif /*_DVBFRONTEND_H_*/
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
deleted file mode 100644
index d41df70..0000000
--- a/include/linux/dvb/frontend.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * frontend.h
- *
- * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
- * Ralph Metzler <ralph@convergence.de>
- * Holger Waechtler <holger@convergence.de>
- * Andre Draszik <ad@convergence.de>
- * for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef _DVBFRONTEND_H_
-#define _DVBFRONTEND_H_
-
-#include <asm/types.h>
-
-
-typedef enum fe_type {
- FE_QPSK,
- FE_QAM,
- FE_OFDM,
- FE_ATSC
-} fe_type_t;
-
-
-typedef enum fe_caps {
- FE_IS_STUPID = 0,
- FE_CAN_INVERSION_AUTO = 0x1,
- FE_CAN_FEC_1_2 = 0x2,
- FE_CAN_FEC_2_3 = 0x4,
- FE_CAN_FEC_3_4 = 0x8,
- FE_CAN_FEC_4_5 = 0x10,
- FE_CAN_FEC_5_6 = 0x20,
- FE_CAN_FEC_6_7 = 0x40,
- FE_CAN_FEC_7_8 = 0x80,
- FE_CAN_FEC_8_9 = 0x100,
- FE_CAN_FEC_AUTO = 0x200,
- FE_CAN_QPSK = 0x400,
- FE_CAN_QAM_16 = 0x800,
- FE_CAN_QAM_32 = 0x1000,
- FE_CAN_QAM_64 = 0x2000,
- FE_CAN_QAM_128 = 0x4000,
- FE_CAN_QAM_256 = 0x8000,
- FE_CAN_QAM_AUTO = 0x10000,
- FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
- FE_CAN_BANDWIDTH_AUTO = 0x40000,
- FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
- FE_CAN_HIERARCHY_AUTO = 0x100000,
- FE_CAN_8VSB = 0x200000,
- FE_CAN_16VSB = 0x400000,
- FE_NEEDS_BENDING = 0x20000000, // not supported anymore, don't use (frontend requires frequency bending)
- FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically
- FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output
-} fe_caps_t;
-
-
-struct dvb_frontend_info {
- char name[128];
- fe_type_t type;
- __u32 frequency_min;
- __u32 frequency_max;
- __u32 frequency_stepsize;
- __u32 frequency_tolerance;
- __u32 symbol_rate_min;
- __u32 symbol_rate_max;
- __u32 symbol_rate_tolerance; /* ppm */
- __u32 notifier_delay; /* DEPRECATED */
- fe_caps_t caps;
-};
-
-
-/**
- * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
- * the meaning of this struct...
- */
-struct dvb_diseqc_master_cmd {
- __u8 msg [6]; /* { framing, address, command, data [3] } */
- __u8 msg_len; /* valid values are 3...6 */
-};
-
-
-struct dvb_diseqc_slave_reply {
- __u8 msg [4]; /* { framing, data [3] } */
- __u8 msg_len; /* valid values are 0...4, 0 means no msg */
- int timeout; /* return from ioctl after timeout ms with */
-}; /* errorcode when no message was received */
-
-
-typedef enum fe_sec_voltage {
- SEC_VOLTAGE_13,
- SEC_VOLTAGE_18,
- SEC_VOLTAGE_OFF
-} fe_sec_voltage_t;
-
-
-typedef enum fe_sec_tone_mode {
- SEC_TONE_ON,
- SEC_TONE_OFF
-} fe_sec_tone_mode_t;
-
-
-typedef enum fe_sec_mini_cmd {
- SEC_MINI_A,
- SEC_MINI_B
-} fe_sec_mini_cmd_t;
-
-
-typedef enum fe_status {
- FE_HAS_SIGNAL = 0x01, /* found something above the noise level */
- FE_HAS_CARRIER = 0x02, /* found a DVB signal */
- FE_HAS_VITERBI = 0x04, /* FEC is stable */
- FE_HAS_SYNC = 0x08, /* found sync bytes */
- FE_HAS_LOCK = 0x10, /* everything's working... */
- FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */
- FE_REINIT = 0x40 /* frontend was reinitialized, */
-} fe_status_t; /* application is recommended to reset */
- /* DiSEqC, tone and parameters */
-
-typedef enum fe_spectral_inversion {
- INVERSION_OFF,
- INVERSION_ON,
- INVERSION_AUTO
-} fe_spectral_inversion_t;
-
-
-typedef enum fe_code_rate {
- FEC_NONE = 0,
- FEC_1_2,
- FEC_2_3,
- FEC_3_4,
- FEC_4_5,
- FEC_5_6,
- FEC_6_7,
- FEC_7_8,
- FEC_8_9,
- FEC_AUTO
-} fe_code_rate_t;
-
-
-typedef enum fe_modulation {
- QPSK,
- QAM_16,
- QAM_32,
- QAM_64,
- QAM_128,
- QAM_256,
- QAM_AUTO,
- VSB_8,
- VSB_16
-} fe_modulation_t;
-
-typedef enum fe_transmit_mode {
- TRANSMISSION_MODE_2K,
- TRANSMISSION_MODE_8K,
- TRANSMISSION_MODE_AUTO
-} fe_transmit_mode_t;
-
-typedef enum fe_bandwidth {
- BANDWIDTH_8_MHZ,
- BANDWIDTH_7_MHZ,
- BANDWIDTH_6_MHZ,
- BANDWIDTH_AUTO
-} fe_bandwidth_t;
-
-
-typedef enum fe_guard_interval {
- GUARD_INTERVAL_1_32,
- GUARD_INTERVAL_1_16,
- GUARD_INTERVAL_1_8,
- GUARD_INTERVAL_1_4,
- GUARD_INTERVAL_AUTO
-} fe_guard_interval_t;
-
-
-typedef enum fe_hierarchy {
- HIERARCHY_NONE,
- HIERARCHY_1,
- HIERARCHY_2,
- HIERARCHY_4,
- HIERARCHY_AUTO
-} fe_hierarchy_t;
-
-
-struct dvb_qpsk_parameters {
- __u32 symbol_rate; /* symbol rate in Symbols per second */
- fe_code_rate_t fec_inner; /* forward error correction (see above) */
-};
-
-struct dvb_qam_parameters {
- __u32 symbol_rate; /* symbol rate in Symbols per second */
- fe_code_rate_t fec_inner; /* forward error correction (see above) */
- fe_modulation_t modulation; /* modulation type (see above) */
-};
-
-struct dvb_vsb_parameters {
- fe_modulation_t modulation; /* modulation type (see above) */
-};
-
-struct dvb_ofdm_parameters {
- fe_bandwidth_t bandwidth;
- fe_code_rate_t code_rate_HP; /* high priority stream code rate */
- fe_code_rate_t code_rate_LP; /* low priority stream code rate */
- fe_modulation_t constellation; /* modulation type (see above) */
- fe_transmit_mode_t transmission_mode;
- fe_guard_interval_t guard_interval;
- fe_hierarchy_t hierarchy_information;
-};
-
-
-struct dvb_frontend_parameters {
- __u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
- /* intermediate frequency in kHz for QPSK */
- fe_spectral_inversion_t inversion;
- union {
- struct dvb_qpsk_parameters qpsk;
- struct dvb_qam_parameters qam;
- struct dvb_ofdm_parameters ofdm;
- struct dvb_vsb_parameters vsb;
- } u;
-};
-
-
-struct dvb_frontend_event {
- fe_status_t status;
- struct dvb_frontend_parameters parameters;
-};
-
-
-
-#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
-
-#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
-#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
-#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
-#define FE_DISEQC_SEND_BURST _IO('o', 65) /* fe_sec_mini_cmd_t */
-
-#define FE_SET_TONE _IO('o', 66) /* fe_sec_tone_mode_t */
-#define FE_SET_VOLTAGE _IO('o', 67) /* fe_sec_voltage_t */
-#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */
-
-#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
-#define FE_READ_BER _IOR('o', 70, __u32)
-#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
-#define FE_READ_SNR _IOR('o', 72, __u16)
-#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
-
-#define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters)
-#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
-#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
-
-#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
-
-#endif /*_DVBFRONTEND_H_*/
diff --git a/include/linux/dvb/net.h b/include/net.h
index 4b8fa51..5be474b 100644
--- a/include/linux/dvb/net.h
+++ b/include/net.h
@@ -1,9 +1,9 @@
-/*
+/*
* net.h
*
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de>
- for convergence integrated media GmbH
+ * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -30,12 +30,24 @@
struct dvb_net_if {
__u16 pid;
__u16 if_num;
+ __u8 feedtype;
+#define DVB_NET_FEEDTYPE_MPE 0 /* multi protocol encapsulation */
+#define DVB_NET_FEEDTYPE_ULE 1 /* ultra lightweight encapsulation */
};
-#define NET_ADD_IF _IOWR('o', 52, struct dvb_net_if)
-#define NET_REMOVE_IF _IO('o', 53)
-#define NET_GET_IF _IOWR('o', 54, struct dvb_net_if)
+#define NET_ADD_IF _IOWR('o', 52, struct dvb_net_if)
+#define NET_REMOVE_IF _IO('o', 53)
+#define NET_GET_IF _IOWR('o', 54, struct dvb_net_if)
-#endif /*_DVBNET_H_*/
+/* binary compatibility cruft: */
+struct __dvb_net_if_old {
+ __u16 pid;
+ __u16 if_num;
+};
+#define __NET_ADD_IF_OLD _IOWR('o', 52, struct __dvb_net_if_old)
+#define __NET_GET_IF_OLD _IOWR('o', 54, struct __dvb_net_if_old)
+
+
+#endif /*_DVBNET_H_*/
diff --git a/include/linux/dvb/osd.h b/include/osd.h
index 0d81439..5d2961c 100644
--- a/include/linux/dvb/osd.h
+++ b/include/osd.h
@@ -1,9 +1,9 @@
-/*
+/*
* osd.h
*
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
- for convergence integrated media GmbH
+ * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public License
@@ -91,21 +91,52 @@ typedef enum {
// TODO: remove "test" in final version
OSD_Text, // (x0,y0,size,color,text)
OSD_SetWindow, // (x0) set window with number 0<x0<8 as current
- OSD_MoveWindow, // move current window to (x0, y0)
+ OSD_MoveWindow, // move current window to (x0, y0)
+ OSD_OpenRaw, // Open other types of OSD windows
} OSD_Command;
typedef struct osd_cmd_s {
- OSD_Command cmd;
- int x0;
- int y0;
- int x1;
- int y1;
- int color;
- void *data;
+ OSD_Command cmd;
+ int x0;
+ int y0;
+ int x1;
+ int y1;
+ int color;
+ void *data;
} osd_cmd_t;
+/* OSD_OpenRaw: set 'color' to desired window type */
+typedef enum {
+ OSD_BITMAP1, /* 1 bit bitmap */
+ OSD_BITMAP2, /* 2 bit bitmap */
+ OSD_BITMAP4, /* 4 bit bitmap */
+ OSD_BITMAP8, /* 8 bit bitmap */
+ OSD_BITMAP1HR, /* 1 Bit bitmap half resolution */
+ OSD_BITMAP2HR, /* 2 bit bitmap half resolution */
+ OSD_BITMAP4HR, /* 4 bit bitmap half resolution */
+ OSD_BITMAP8HR, /* 8 bit bitmap half resolution */
+ OSD_YCRCB422, /* 4:2:2 YCRCB Graphic Display */
+ OSD_YCRCB444, /* 4:4:4 YCRCB Graphic Display */
+ OSD_YCRCB444HR, /* 4:4:4 YCRCB graphic half resolution */
+ OSD_VIDEOTSIZE, /* True Size Normal MPEG Video Display */
+ OSD_VIDEOHSIZE, /* MPEG Video Display Half Resolution */
+ OSD_VIDEOQSIZE, /* MPEG Video Display Quarter Resolution */
+ OSD_VIDEODSIZE, /* MPEG Video Display Double Resolution */
+ OSD_VIDEOTHSIZE, /* True Size MPEG Video Display Half Resolution */
+ OSD_VIDEOTQSIZE, /* True Size MPEG Video Display Quarter Resolution*/
+ OSD_VIDEOTDSIZE, /* True Size MPEG Video Display Double Resolution */
+ OSD_VIDEONSIZE, /* Full Size MPEG Video Display */
+ OSD_CURSOR /* Cursor */
+} osd_raw_window_t;
-#define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t)
+typedef struct osd_cap_s {
+ int cmd;
+#define OSD_CAP_MEMSIZE 1 /* memory size */
+ long val;
+} osd_cap_t;
-#endif
+#define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t)
+#define OSD_GET_CAPABILITY _IOR('o', 161, osd_cap_t)
+
+#endif
diff --git a/include/linux/dvb/version.h b/include/version.h
index 54e256e..2dd76c8 100644
--- a/include/linux/dvb/version.h
+++ b/include/version.h
@@ -24,6 +24,6 @@
#define _DVBVERSION_H_
#define DVB_API_VERSION 3
+#define DVB_API_VERSION_MINOR 3
#endif /*_DVBVERSION_H_*/
-
diff --git a/include/linux/dvb/video.h b/include/video.h
index a8b6008..317ba6b 100644
--- a/include/linux/dvb/video.h
+++ b/include/video.h
@@ -1,9 +1,9 @@
-/*
+/*
* video.h
*
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de>
- for convergence integrated media GmbH
+ * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -27,6 +27,7 @@
#ifdef __KERNEL__
#include <linux/types.h>
#else
+#include <asm/types.h>
#include <stdint.h>
#include <time.h>
#endif
@@ -34,25 +35,25 @@
typedef enum {
VIDEO_FORMAT_4_3, /* Select 4:3 format */
- VIDEO_FORMAT_16_9, /* Select 16:9 format. */
+ VIDEO_FORMAT_16_9, /* Select 16:9 format. */
VIDEO_FORMAT_221_1 /* 2.21:1 */
} video_format_t;
typedef enum {
- VIDEO_SYSTEM_PAL,
- VIDEO_SYSTEM_NTSC,
- VIDEO_SYSTEM_PALN,
- VIDEO_SYSTEM_PALNc,
- VIDEO_SYSTEM_PALM,
- VIDEO_SYSTEM_NTSC60,
+ VIDEO_SYSTEM_PAL,
+ VIDEO_SYSTEM_NTSC,
+ VIDEO_SYSTEM_PALN,
+ VIDEO_SYSTEM_PALNc,
+ VIDEO_SYSTEM_PALM,
+ VIDEO_SYSTEM_NTSC60,
VIDEO_SYSTEM_PAL60,
VIDEO_SYSTEM_PALM60
} video_system_t;
-typedef enum {
- VIDEO_PAN_SCAN, /* use pan and scan format */
+typedef enum {
+ VIDEO_PAN_SCAN, /* use pan and scan format */
VIDEO_LETTER_BOX, /* use letterbox format */
VIDEO_CENTER_CUT_OUT /* use center cut out format */
} video_displayformat_t;
@@ -64,62 +65,120 @@ typedef struct {
} video_size_t;
typedef enum {
- VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
- VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
- comes from the user through the write
- system call */
+ VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
+ VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
+ comes from the user through the write
+ system call */
} video_stream_source_t;
typedef enum {
- VIDEO_STOPPED, /* Video is stopped */
- VIDEO_PLAYING, /* Video is currently playing */
- VIDEO_FREEZED /* Video is freezed */
-} video_play_state_t;
-
+ VIDEO_STOPPED, /* Video is stopped */
+ VIDEO_PLAYING, /* Video is currently playing */
+ VIDEO_FREEZED /* Video is freezed */
+} video_play_state_t;
+
+
+/* Decoder commands */
+#define VIDEO_CMD_PLAY (0)
+#define VIDEO_CMD_STOP (1)
+#define VIDEO_CMD_FREEZE (2)
+#define VIDEO_CMD_CONTINUE (3)
+
+/* Flags for VIDEO_CMD_FREEZE */
+#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)
+
+/* Flags for VIDEO_CMD_STOP */
+#define VIDEO_CMD_STOP_TO_BLACK (1 << 0)
+#define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1)
+
+/* Play input formats: */
+/* The decoder has no special format requirements */
+#define VIDEO_PLAY_FMT_NONE (0)
+/* The decoder requires full GOPs */
+#define VIDEO_PLAY_FMT_GOP (1)
+
+/* The structure must be zeroed before use by the application
+ This ensures it can be extended safely in the future. */
+struct video_command {
+ __u32 cmd;
+ __u32 flags;
+ union {
+ struct {
+ __u64 pts;
+ } stop;
+
+ struct {
+ /* 0 or 1000 specifies normal speed,
+ 1 specifies forward single stepping,
+ -1 specifies backward single stepping,
+ >1: playback at speed/1000 of the normal speed,
+ <-1: reverse playback at (-speed/1000) of the normal speed. */
+ __s32 speed;
+ __u32 format;
+ } play;
+
+ struct {
+ __u32 data[16];
+ } raw;
+ };
+};
-struct video_event {
- int32_t type;
-#define VIDEO_EVENT_SIZE_CHANGED 1
- time_t timestamp;
+/* FIELD_UNKNOWN can be used if the hardware does not know whether
+ the Vsync is for an odd, even or progressive (i.e. non-interlaced)
+ field. */
+#define VIDEO_VSYNC_FIELD_UNKNOWN (0)
+#define VIDEO_VSYNC_FIELD_ODD (1)
+#define VIDEO_VSYNC_FIELD_EVEN (2)
+#define VIDEO_VSYNC_FIELD_PROGRESSIVE (3)
+
+struct video_event {
+ int32_t type;
+#define VIDEO_EVENT_SIZE_CHANGED 1
+#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
+#define VIDEO_EVENT_DECODER_STOPPED 3
+#define VIDEO_EVENT_VSYNC 4
+ time_t timestamp;
union {
- video_size_t size;
+ video_size_t size;
+ unsigned int frame_rate; /* in frames per 1000sec */
+ unsigned char vsync_field; /* unknown/odd/even/progressive */
} u;
};
-struct video_status {
- int video_blank; /* blank video on freeze? */
- video_play_state_t play_state; /* current state of playback */
- video_stream_source_t stream_source; /* current source (demux/memory) */
- video_format_t video_format; /* current aspect ratio of stream*/
- video_displayformat_t display_format;/* selected cropping mode */
+struct video_status {
+ int video_blank; /* blank video on freeze? */
+ video_play_state_t play_state; /* current state of playback */
+ video_stream_source_t stream_source; /* current source (demux/memory) */
+ video_format_t video_format; /* current aspect ratio of stream*/
+ video_displayformat_t display_format;/* selected cropping mode */
};
struct video_still_picture {
- char *iFrame; /* pointer to a single iframe in memory */
- int32_t size;
+ char *iFrame; /* pointer to a single iframe in memory */
+ int32_t size;
};
-typedef
+typedef
struct video_highlight {
int active; /* 1=show highlight, 0=hide highlight */
uint8_t contrast1; /* 7- 4 Pattern pixel contrast */
- /* 3- 0 Background pixel contrast */
+ /* 3- 0 Background pixel contrast */
uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */
- /* 3- 0 Emphasis pixel-1 contrast */
+ /* 3- 0 Emphasis pixel-1 contrast */
uint8_t color1; /* 7- 4 Pattern pixel color */
- /* 3- 0 Background pixel color */
+ /* 3- 0 Background pixel color */
uint8_t color2; /* 7- 4 Emphasis pixel-2 color */
- /* 3- 0 Emphasis pixel-1 color */
- uint32_t ypos; /* 23-22 auto action mode */
- /* 21-12 start y */
- /* 9- 0 end y */
+ /* 3- 0 Emphasis pixel-1 color */
+ uint32_t ypos; /* 23-22 auto action mode */
+ /* 21-12 start y */
+ /* 9- 0 end y */
uint32_t xpos; /* 23-22 button color number */
- /* 21-12 start x */
- /* 9- 0 end x */
+ /* 21-12 start x */
+ /* 9- 0 end x */
} video_highlight_t;
@@ -156,21 +215,21 @@ typedef uint16_t video_attributes_t;
/* bit definitions for capabilities: */
/* can the hardware decode MPEG1 and/or MPEG2? */
-#define VIDEO_CAP_MPEG1 1
+#define VIDEO_CAP_MPEG1 1
#define VIDEO_CAP_MPEG2 2
/* can you send a system and/or program stream to video device?
- (you still have to open the video and the audio device but only
+ (you still have to open the video and the audio device but only
send the stream to the video device) */
#define VIDEO_CAP_SYS 4
#define VIDEO_CAP_PROG 8
-/* can the driver also handle SPU, NAVI and CSS encoded data?
+/* can the driver also handle SPU, NAVI and CSS encoded data?
(CSS API is not present yet) */
#define VIDEO_CAP_SPU 16
#define VIDEO_CAP_NAVI 32
#define VIDEO_CAP_CSS 64
-#define VIDEO_STOP _IO('o', 21)
+#define VIDEO_STOP _IO('o', 21)
#define VIDEO_PLAY _IO('o', 22)
#define VIDEO_FREEZE _IO('o', 23)
#define VIDEO_CONTINUE _IO('o', 24)
@@ -194,6 +253,25 @@ typedef uint16_t video_attributes_t;
#define VIDEO_GET_NAVI _IOR('o', 52, video_navi_pack_t)
#define VIDEO_SET_ATTRIBUTES _IO('o', 53)
#define VIDEO_GET_SIZE _IOR('o', 55, video_size_t)
+#define VIDEO_GET_FRAME_RATE _IOR('o', 56, unsigned int)
-#endif /*_DVBVIDEO_H_*/
+/**
+ * VIDEO_GET_PTS
+ *
+ * Read the 33 bit presentation time stamp as defined
+ * in ITU T-REC-H.222.0 / ISO/IEC 13818-1.
+ *
+ * The PTS should belong to the currently played
+ * frame if possible, but may also be a value close to it
+ * like the PTS of the last decoded frame or the last PTS
+ * extracted by the PES parser.
+ */
+#define VIDEO_GET_PTS _IOR('o', 57, __u64)
+
+/* Read the number of displayed frames since the decoder was started */
+#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64)
+#define VIDEO_COMMAND _IOWR('o', 59, struct video_command)
+#define VIDEO_TRY_COMMAND _IOWR('o', 60, struct video_command)
+
+#endif /*_DVBVIDEO_H_*/
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..3389628
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,11 @@
+# Makefile for linuxtv.org dvb-apps/lib
+
+.PHONY: all clean install
+
+all clean install:
+ $(MAKE) -C libdvbapi $@
+ $(MAKE) -C libdvbcfg $@
+ $(MAKE) -C libdvben50221 $@
+ $(MAKE) -C libdvbsec $@
+ $(MAKE) -C libesg $@
+ $(MAKE) -C libucsi $@
diff --git a/lib/libdvbapi/Makefile b/lib/libdvbapi/Makefile
new file mode 100644
index 0000000..0ed96ec
--- /dev/null
+++ b/lib/libdvbapi/Makefile
@@ -0,0 +1,25 @@
+# Makefile for linuxtv.org dvb-apps/lib/libdvbapi
+
+includes = dvbaudio.h \
+ dvbca.h \
+ dvbdemux.h \
+ dvbfe.h \
+ dvbnet.h \
+ dvbvideo.h
+
+objects = dvbaudio.o \
+ dvbca.o \
+ dvbdemux.o \
+ dvbfe.o \
+ dvbnet.o \
+ dvbvideo.o
+
+lib_name = libdvbapi
+
+CPPFLAGS += -I../../lib
+
+.PHONY: all
+
+all: library
+
+include ../../Make.rules
diff --git a/lib/libdvbapi/dvbaudio.c b/lib/libdvbapi/dvbaudio.c
new file mode 100644
index 0000000..72b4d70
--- /dev/null
+++ b/lib/libdvbapi/dvbaudio.c
@@ -0,0 +1,50 @@
+/*
+ * libdvbnet - a DVB network support library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/dvb/audio.h>
+#include <errno.h>
+#include "dvbaudio.h"
+
+int dvbaudio_open(int adapter, int audiodeviceid)
+{
+ char filename[PATH_MAX+1];
+ int fd;
+
+ sprintf(filename, "/dev/dvb/adapter%i/audio%i", adapter, audiodeviceid);
+ if ((fd = open(filename, O_RDWR)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.audio%i", adapter, audiodeviceid);
+ fd = open(filename, O_RDWR);
+ }
+
+ return fd;
+}
+
+int dvbaudio_set_bypass(int fd, int bypass)
+{
+ return ioctl(fd, AUDIO_SET_BYPASS_MODE, bypass);
+}
diff --git a/lib/libdvbapi/dvbaudio.h b/lib/libdvbapi/dvbaudio.h
new file mode 100644
index 0000000..36f6a55
--- /dev/null
+++ b/lib/libdvbapi/dvbaudio.h
@@ -0,0 +1,55 @@
+/*
+ * libdvbnet - a DVB network support library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LIBDVBAUDIO_H
+#define LIBDVBAUDIO_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * Open a DVB audio device.
+ *
+ * @param adapter DVB adapter ID.
+ * @param audiodeviceid Id of audio device of that adapter to open.
+ * @return A unix file descriptor on success, or -1 on failure.
+ */
+extern int dvbaudio_open(int adapter, int audiodeviceid);
+
+/**
+ * Control audio bypass - i.e. output decoded audio, or the raw bitstream (e.g. AC3).
+ *
+ * @param fd Audio device opened with dvbaudio_open().
+ * @param bypass 1=> enable bypass, 0=> disable.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbaudio_set_bypass(int fd, int bypass);
+
+// FIXME: this is a stub library
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBDVBAUDIO_H
diff --git a/lib/libdvbapi/dvbca.c b/lib/libdvbapi/dvbca.c
new file mode 100644
index 0000000..8261cd2
--- /dev/null
+++ b/lib/libdvbapi/dvbca.c
@@ -0,0 +1,159 @@
+/*
+ * libdvbca - interface onto raw CA devices
+ *
+ * Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <linux/dvb/ca.h>
+#include "dvbca.h"
+
+
+int dvbca_open(int adapter, int cadevice)
+{
+ char filename[PATH_MAX+1];
+ int fd;
+
+ sprintf(filename, "/dev/dvb/adapter%i/ca%i", adapter, cadevice);
+ if ((fd = open(filename, O_RDWR)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.ca%i", adapter, cadevice);
+ fd = open(filename, O_RDWR);
+ }
+
+ return fd;
+}
+
+int dvbca_reset(int fd, uint8_t slot)
+{
+ return ioctl(fd, CA_RESET, (1 << slot));
+}
+
+int dvbca_get_interface_type(int fd, uint8_t slot)
+{
+ ca_slot_info_t info;
+
+ info.num = slot;
+ if (ioctl(fd, CA_GET_SLOT_INFO, &info))
+ return -1;
+
+ if (info.type & CA_CI_LINK)
+ return DVBCA_INTERFACE_LINK;
+ if (info.type & CA_CI)
+ return DVBCA_INTERFACE_HLCI;
+
+ return -1;
+}
+
+int dvbca_get_cam_state(int fd, uint8_t slot)
+{
+ ca_slot_info_t info;
+
+ info.num = slot;
+ if (ioctl(fd, CA_GET_SLOT_INFO, &info))
+ return -1;
+
+ if (info.flags == 0)
+ return DVBCA_CAMSTATE_MISSING;
+ if (info.flags & CA_CI_MODULE_READY)
+ return DVBCA_CAMSTATE_READY;
+ if (info.flags & CA_CI_MODULE_PRESENT)
+ return DVBCA_CAMSTATE_INITIALISING;
+
+ return -1;
+}
+
+int dvbca_link_write(int fd, uint8_t slot, uint8_t connection_id,
+ uint8_t *data, uint16_t data_length)
+{
+ uint8_t *buf = malloc(data_length + 2);
+ if (buf == NULL)
+ return -1;
+
+ buf[0] = slot;
+ buf[1] = connection_id;
+ memcpy(buf+2, data, data_length);
+
+ int result = write(fd, buf, data_length+2);
+ free(buf);
+ return result;
+}
+
+int dvbca_link_read(int fd, uint8_t *slot, uint8_t *connection_id,
+ uint8_t *data, uint16_t data_length)
+{
+ int size;
+
+ uint8_t *buf = malloc(data_length + 2);
+ if (buf == NULL)
+ return -1;
+
+ if ((size = read(fd, buf, data_length+2)) < 2)
+ return -1;
+
+ *slot = buf[0];
+ *connection_id = buf[1];
+ memcpy(data, buf+2, size-2);
+ free(buf);
+
+ return size - 2;
+}
+
+int dvbca_hlci_write(int fd, uint8_t *data, uint16_t data_length)
+{
+ struct ca_msg msg;
+
+ if (data_length > 256) {
+ return -1;
+ }
+ memset(&msg, 0, sizeof(msg));
+ msg.length = data_length;
+
+ memcpy(msg.msg, data, data_length);
+
+ return ioctl(fd, CA_SEND_MSG, &msg);
+}
+
+int dvbca_hlci_read(int fd, uint32_t app_tag, uint8_t *data,
+ uint16_t data_length)
+{
+ struct ca_msg msg;
+
+ if (data_length > 256) {
+ data_length = 256;
+ }
+ memset(&msg, 0, sizeof(msg));
+ msg.length = data_length;
+ msg.msg[0] = app_tag >> 16;
+ msg.msg[1] = app_tag >> 8;
+ msg.msg[2] = app_tag;
+
+ int status = ioctl(fd, CA_GET_MSG, &msg);
+ if (status < 0) return status;
+
+ if (msg.length > data_length) msg.length = data_length;
+ memcpy(data, msg.msg, msg.length);
+ return msg.length;
+}
diff --git a/lib/libdvbapi/dvbca.h b/lib/libdvbapi/dvbca.h
new file mode 100644
index 0000000..c65423b
--- /dev/null
+++ b/lib/libdvbapi/dvbca.h
@@ -0,0 +1,135 @@
+/*
+ * libdvbca - interface onto raw CA devices
+ *
+ * Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LIBDVBCA_H
+#define LIBDVBCA_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * The types of CA interface we support.
+ */
+#define DVBCA_INTERFACE_LINK 0
+#define DVBCA_INTERFACE_HLCI 1
+
+/**
+ * States a CAM in a slot can be in.
+ */
+#define DVBCA_CAMSTATE_MISSING 0
+#define DVBCA_CAMSTATE_INITIALISING 1
+#define DVBCA_CAMSTATE_READY 2
+
+
+/**
+ * Open a CA device. Multiple CAMs can be accessed through a CA device.
+ *
+ * @param adapter Index of the DVB adapter.
+ * @param cadevice Index of the CA device on that adapter (usually 0).
+ * @return A unix file descriptor on success, or -1 on failure.
+ */
+extern int dvbca_open(int adapter, int cadevice);
+
+/**
+ * Reset a CAM.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param slot Slot where the requested CAM is in.
+ * @return 0 on success, -1 on failure.
+ */
+extern int dvbca_reset(int fd, uint8_t slot);
+
+/**
+ * Get the interface type of a CAM.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param slot Slot where the requested CAM is in.
+ * @return One of the DVBCA_INTERFACE_* values, or -1 on failure.
+ */
+extern int dvbca_get_interface_type(int fd, uint8_t slot);
+
+/**
+ * Get the state of a CAM.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param slot Slot where the requested CAM is in.
+ * @return One of the DVBCA_CAMSTATE_* values, or -1 on failure.
+ */
+extern int dvbca_get_cam_state(int fd, uint8_t slot);
+
+/**
+ * Write a message to a CAM using a link-layer interface.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param slot Slot where the requested CAM is in.
+ * @param connection_id Connection ID of the message.
+ * @param data Data to write.
+ * @param data_length Number of bytes to write.
+ * @return 0 on success, or -1 on failure.
+ */
+extern int dvbca_link_write(int fd, uint8_t slot, uint8_t connection_id,
+ uint8_t *data, uint16_t data_length);
+
+/**
+ * Read a message from a CAM using a link-layer interface.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param slot Slot where the responding CAM is in.
+ * @param connection_id Destination for the connection ID the message came from.
+ * @param data Data that was read.
+ * @param data_length Max number of bytes to read.
+ * @return Number of bytes read on success, or -1 on failure.
+ */
+extern int dvbca_link_read(int fd, uint8_t *slot, uint8_t *connection_id,
+ uint8_t *data, uint16_t data_length);
+
+// FIXME how do we determine which CAM slot of a CA is meant?
+/**
+ * Write a message to a CAM using an HLCI interface.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param data Data to write.
+ * @param data_length Number of bytes to write.
+ * @return 0 on success, or -1 on failure.
+ */
+extern int dvbca_hlci_write(int fd, uint8_t *data, uint16_t data_length);
+
+// FIXME how do we determine which CAM slot of a CA is meant?
+/**
+ * Read a message from a CAM using an HLCI interface.
+ *
+ * @param fd File handle opened with dvbca_open.
+ * @param app_tag Application layer tag giving the message type to read.
+ * @param data Data that was read.
+ * @param data_length Max number of bytes to read.
+ * @return Number of bytes read on success, or -1 on failure.
+ */
+extern int dvbca_hlci_read(int fd, uint32_t app_tag, uint8_t *data,
+ uint16_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBDVBCA_H
diff --git a/lib/libdvbapi/dvbdemux.c b/lib/libdvbapi/dvbdemux.c
new file mode 100644
index 0000000..a882af6
--- /dev/null
+++ b/lib/libdvbapi/dvbdemux.c
@@ -0,0 +1,255 @@
+/*
+ * libdvbdemux - a DVB demux library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <linux/dvb/dmx.h>
+#include "dvbdemux.h"
+
+
+int dvbdemux_open_demux(int adapter, int demuxdevice, int nonblocking)
+{
+ char filename[PATH_MAX+1];
+ int flags = O_RDWR;
+ int fd;
+
+ if (nonblocking)
+ flags |= O_NONBLOCK;
+
+ sprintf(filename, "/dev/dvb/adapter%i/demux%i", adapter, demuxdevice);
+ if ((fd = open(filename, flags)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.demux%i", adapter, demuxdevice);
+ fd = open(filename, flags);
+ }
+
+ return fd;
+}
+
+int dvbdemux_open_dvr(int adapter, int dvrdevice, int readonly, int nonblocking)
+{
+ char filename[PATH_MAX+1];
+ int flags = O_RDWR;
+ int fd;
+
+ if (readonly)
+ flags = O_RDONLY;
+ if (nonblocking)
+ flags |= O_NONBLOCK;
+
+ sprintf(filename, "/dev/dvb/adapter%i/dvr%i", adapter, dvrdevice);
+ if ((fd = open(filename, flags)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.dvr%i", adapter, dvrdevice);
+ fd = open(filename, flags);
+ }
+
+ return fd;
+}
+
+int dvbdemux_set_section_filter(int fd, int pid,
+ uint8_t filter[18], uint8_t mask[18],
+ int start, int checkcrc)
+{
+ struct dmx_sct_filter_params sctfilter;
+
+ memset(&sctfilter, 0, sizeof(sctfilter));
+ sctfilter.pid = pid;
+ memcpy(sctfilter.filter.filter, filter, 1);
+ memcpy(sctfilter.filter.filter+1, filter+3, 15);
+ memcpy(sctfilter.filter.mask, mask, 1);
+ memcpy(sctfilter.filter.mask+1, mask+3, 15);
+ memset(sctfilter.filter.mode, 0, 16);
+ if (start)
+ sctfilter.flags |= DMX_IMMEDIATE_START;
+ if (checkcrc)
+ sctfilter.flags |= DMX_CHECK_CRC;
+
+ return ioctl(fd, DMX_SET_FILTER, &sctfilter);
+}
+
+int dvbdemux_set_pes_filter(int fd, int pid,
+ int input, int output,
+ int pestype,
+ int start)
+{
+ struct dmx_pes_filter_params filter;
+
+ memset(&filter, 0, sizeof(filter));
+ filter.pid = pid;
+
+ switch(input) {
+ case DVBDEMUX_INPUT_FRONTEND:
+ filter.input = DMX_IN_FRONTEND;
+ break;
+
+ case DVBDEMUX_INPUT_DVR:
+ filter.input = DMX_IN_DVR;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ switch(output) {
+ case DVBDEMUX_OUTPUT_DECODER:
+ filter.output = DMX_OUT_DECODER;
+ break;
+
+ case DVBDEMUX_OUTPUT_DEMUX:
+ filter.output = DMX_OUT_TAP;
+ break;
+
+ case DVBDEMUX_OUTPUT_DVR:
+ filter.output = DMX_OUT_TS_TAP;
+ break;
+
+#ifdef DMX_OUT_TSDEMUX_TAP
+ case DVBDEMUX_OUTPUT_TS_DEMUX:
+ filter.output = DMX_OUT_TSDEMUX_TAP;
+ break;
+#endif
+
+ default:
+ return -EINVAL;
+ }
+
+ switch(pestype) {
+ case DVBDEMUX_PESTYPE_AUDIO:
+ filter.pes_type = DMX_PES_AUDIO;
+ break;
+
+ case DVBDEMUX_PESTYPE_VIDEO:
+ filter.pes_type = DMX_PES_VIDEO;
+ break;
+
+ case DVBDEMUX_PESTYPE_TELETEXT:
+ filter.pes_type = DMX_PES_TELETEXT;
+ break;
+
+ case DVBDEMUX_PESTYPE_SUBTITLE:
+ filter.pes_type = DMX_PES_SUBTITLE;
+ break;
+
+ case DVBDEMUX_PESTYPE_PCR:
+ filter.pes_type = DMX_PES_PCR;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (start)
+ filter.flags |= DMX_IMMEDIATE_START;
+
+ return ioctl(fd, DMX_SET_PES_FILTER, &filter);
+}
+
+int dvbdemux_set_pid_filter(int fd, int pid,
+ int input, int output,
+ int start)
+{
+ struct dmx_pes_filter_params filter;
+
+ memset(&filter, 0, sizeof(filter));
+ if (pid == -1)
+ filter.pid = 0x2000;
+ else
+ filter.pid = pid;
+
+ switch(input) {
+ case DVBDEMUX_INPUT_FRONTEND:
+ filter.input = DMX_IN_FRONTEND;
+ break;
+
+ case DVBDEMUX_INPUT_DVR:
+ filter.input = DMX_IN_DVR;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ switch(output) {
+ case DVBDEMUX_OUTPUT_DECODER:
+ filter.output = DMX_OUT_DECODER;
+ break;
+
+ case DVBDEMUX_OUTPUT_DEMUX:
+ filter.output = DMX_OUT_TAP;
+ break;
+
+ case DVBDEMUX_OUTPUT_DVR:
+ filter.output = DMX_OUT_TS_TAP;
+ break;
+
+#ifdef DMX_OUT_TSDEMUX_TAP
+ case DVBDEMUX_OUTPUT_TS_DEMUX:
+ filter.output = DMX_OUT_TSDEMUX_TAP;
+ break;
+#endif
+
+ default:
+ return -EINVAL;
+ }
+
+ filter.pes_type = DMX_PES_OTHER;
+
+ if (start)
+ filter.flags |= DMX_IMMEDIATE_START;
+
+ return ioctl(fd, DMX_SET_PES_FILTER, &filter);
+}
+
+int dvbdemux_start(int fd)
+{
+ return ioctl(fd, DMX_START);
+}
+
+int dvbdemux_stop(int fd)
+{
+ return ioctl(fd, DMX_STOP);
+}
+
+int dvbdemux_get_stc(int fd, uint64_t *stc)
+{
+ struct dmx_stc _stc;
+ int result;
+
+ memset(stc, 0, sizeof(_stc));
+ if ((result = ioctl(fd, DMX_GET_STC, &_stc)) != 0) {
+ return result;
+ }
+
+ *stc = _stc.stc / _stc.base;
+ return 0;
+}
+
+int dvbdemux_set_buffer(int fd, int bufsize)
+{
+ return ioctl(fd, DMX_SET_BUFFER_SIZE, bufsize);
+}
diff --git a/lib/libdvbapi/dvbdemux.h b/lib/libdvbapi/dvbdemux.h
new file mode 100644
index 0000000..808ee80
--- /dev/null
+++ b/lib/libdvbapi/dvbdemux.h
@@ -0,0 +1,204 @@
+/*
+ * libdvbdemux - a DVB demux library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LIBDVBDEMUX_H
+#define LIBDVBDEMUX_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * Source of the data to be demuxed.
+ *
+ * FRONTEND. The data will be read from the frontend on the adapter.
+ *
+ * DVR. The data will be read from the DVR device of the adapter (of course,
+ * you need to write data TO the DVR device as well).
+ */
+#define DVBDEMUX_INPUT_FRONTEND 0
+#define DVBDEMUX_INPUT_DVR 1
+
+/**
+ * Destination of the demuxed data.
+ *
+ * DECODER. Sends the data directly to a hardware decoder (if present).
+ *
+ * DEMUX. Sends the PID stream to the current demux file descriptor. HOWEVER, the
+ * data will be the payload *only* - transport stream headers will be stripped.
+ *
+ * DVR sends the data to the DVR device. The data will be the complete transport
+ * stream packets with headers intact. Note: if multiple filters specify
+ * DVBDEMUX_OUTPUT_DVR, the individual PID streams will be re-multiplexed
+ * together.
+ */
+#define DVBDEMUX_OUTPUT_DECODER 0
+#define DVBDEMUX_OUTPUT_DEMUX 1
+#define DVBDEMUX_OUTPUT_DVR 2
+#define DVBDEMUX_OUTPUT_TS_DEMUX 3
+
+/**
+ * PES types.
+ */
+#define DVBDEMUX_PESTYPE_AUDIO 0
+#define DVBDEMUX_PESTYPE_VIDEO 1
+#define DVBDEMUX_PESTYPE_TELETEXT 2
+#define DVBDEMUX_PESTYPE_SUBTITLE 3
+#define DVBDEMUX_PESTYPE_PCR 4
+
+
+/**
+ * Open a demux device. Can be called multiple times. These let you setup a
+ * single filter per FD. It can can also be read() from if you use a section
+ * filter, or create a pes_filter or raw_filter with output DVBDEMUX_OUTPUT_DEMUX.
+ *
+ * @param adapter Index of the DVB adapter.
+ * @param demuxdevice Index of the demux device on that adapter (usually 0).
+ * @param nonblocking If 1, frontend will be opened in nonblocking mode.
+ * @return A unix file descriptor on success, or -1 on failure.
+ */
+extern int dvbdemux_open_demux(int adapter, int demuxdevice, int nonblocking);
+
+/**
+ * Open a DVR device. May be opened for writing or reading once.
+ * It is used to either write() transport stream data to be demuxed
+ * (if input == DVBDEMUX_INPUT_DVR), or to read() a stream of demuxed data
+ * (if output == DVBDEMUX_OUTPUT_DVR).
+ *
+ * Note, all demux filters with output set to DVBDEMUX_OUTPUT_DVR will be
+ * multiplexed together and output their data on this device.
+ *
+ * @param adapter Index of the DVB adapter.
+ * @param dvrdevice Index of the dvr device on that adapter (usually 0)
+ * @param readonly If 1, frontend will be opened in readonly mode only.
+ * @param nonblocking If 1, frontend will be opened in nonblocking mode.
+ * @return A unix file descriptor on success, or -1 on failure.
+ */
+extern int dvbdemux_open_dvr(int adapter, int dvrdevice, int readonly, int nonblocking);
+
+/**
+ * Set filter for the first 18 bytes of decoded SI table sections. Note that
+ * bytes 1 and 2 are _not_ filtered since they contain the length field.
+ *
+ * Conceptually, the driver computes the following for each filtered bit.
+ *
+ * (filter[X].bit[Y] & mask[X].bit[Y]) == (header[X].bit[Y] & mask[X].bit[Y])
+ *
+ * Any sections which do not match this criteria for every bit will be discarded.
+ *
+ * The SI data is always read from the frontend, and is always returned by
+ * read()ing the demux fd. FIXME: check this statement!
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @param pid PID of the stream.
+ * @param filter The filter values of the first 18 bytes of the desired sections.
+ * @param mask Bitmask indicating which bits in the filter array should be tested
+ * (if a bit is 1, it will be tested).
+ * @param start If 1, the filter will be started immediately. Otherwise you must
+ * call dvbdemux_start() manually.
+ * @param checkcrc If 1, the driver will check the CRC on the table sections.
+ * Any bad sections will be dropped.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_set_section_filter(int fd, int pid,
+ uint8_t filter[18], uint8_t mask[18],
+ int start, int checkcrc);
+
+/**
+ * Set filter for a stream of PES data. This call can only used for cards
+ * equipped with a hardware decoder.
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @param pid PID of the stream.
+ * @param input One of DVBDEMUX_INPUT_*.
+ * @param output One of DVBDEMUX_OUTPUT_*.
+ * @param pestype One of DVBDEMUX_PESTYPE_* - this tells the decoder the type
+ * of data in this stream.
+ * @param start If 1, the filter will be started immediately. Otherwise you must
+ * call dvbdemux_start() manually.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_set_pes_filter(int fd, int pid,
+ int input, int output,
+ int pestype,
+ int start);
+
+/**
+ * Create a pid filter - this will extract transport stream packets for a
+ * specified PID.
+ *
+ * Note: The wildcard PID can only be used on "budget" cards.
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @param pid PID to retrieve, or use -1 as a wildcard for ALL PIDs.
+ * @param input One of DVBDEMUX_INPUT_*.
+ * @param output One of DVBDEMUX_OUTPUT_*.
+ * @param start If 1, the filter will be started immediately. Otherwise you must
+ * call dvbdemux_start() manually.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_set_pid_filter(int fd, int pid,
+ int input, int output,
+ int start);
+
+/**
+ * Start a demux going.
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_start(int fd);
+
+/**
+ * Stop a demux.
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_stop(int fd);
+
+/**
+ * Retrieve the current STC from the demux. This call can only used for cards
+ * equipped with a hardware decoder.
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @param stc Where to put the retrieved STC value (in 90kHz clock).
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_get_stc(int fd, uint64_t *stc);
+
+/**
+ * Change the internal buffer size used by the demuxer. The default buffer size
+ * is 8192 bytes. Can only be used if the demux in question is stopped.
+ *
+ * @param fd FD as opened with dvbdemux_open_demux() above.
+ * @param bufsize New buffer size to use.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbdemux_set_buffer(int fd, int bufsize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBDVBDEMUX_H
diff --git a/lib/libdvbapi/dvbfe.c b/lib/libdvbapi/dvbfe.c
new file mode 100644
index 0000000..98104c9
--- /dev/null
+++ b/lib/libdvbapi/dvbfe.c
@@ -0,0 +1,574 @@
+/*
+ * libdvbfe - a DVB frontend library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <linux/dvb/frontend.h>
+#include <libdvbmisc/dvbmisc.h>
+#include "dvbfe.h"
+
+int verbose = 0;
+
+static int dvbfe_spectral_inversion_to_kapi[][2] =
+{
+ { DVBFE_INVERSION_OFF, INVERSION_OFF },
+ { DVBFE_INVERSION_ON, INVERSION_ON },
+ { DVBFE_INVERSION_AUTO, INVERSION_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_code_rate_to_kapi[][2] =
+{
+ { DVBFE_FEC_NONE, FEC_NONE },
+ { DVBFE_FEC_1_2, FEC_1_2 },
+ { DVBFE_FEC_2_3, FEC_2_3 },
+ { DVBFE_FEC_3_4, FEC_3_4 },
+ { DVBFE_FEC_4_5, FEC_4_5 },
+ { DVBFE_FEC_5_6, FEC_5_6 },
+ { DVBFE_FEC_6_7, FEC_6_7 },
+ { DVBFE_FEC_7_8, FEC_7_8 },
+ { DVBFE_FEC_8_9, FEC_8_9 },
+ { DVBFE_FEC_AUTO, FEC_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_dvbt_const_to_kapi[][2] =
+{
+ { DVBFE_DVBT_CONST_QPSK, FE_QPSK },
+ { DVBFE_DVBT_CONST_QAM_16, QAM_16 },
+ { DVBFE_DVBT_CONST_QAM_32, QAM_32 },
+ { DVBFE_DVBT_CONST_QAM_64, QAM_64 },
+ { DVBFE_DVBT_CONST_QAM_128, QAM_128 },
+ { DVBFE_DVBT_CONST_QAM_256, QAM_256 },
+ { DVBFE_DVBT_CONST_AUTO, QAM_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_dvbc_mod_to_kapi[][2] =
+{
+ { DVBFE_DVBC_MOD_QAM_16, QAM_16 },
+ { DVBFE_DVBC_MOD_QAM_32, QAM_32 },
+ { DVBFE_DVBC_MOD_QAM_64, QAM_64 },
+ { DVBFE_DVBC_MOD_QAM_128, QAM_128 },
+ { DVBFE_DVBC_MOD_QAM_256, QAM_256 },
+ { DVBFE_DVBC_MOD_AUTO, QAM_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_atsc_mod_to_kapi[][2] =
+{
+ { DVBFE_ATSC_MOD_QAM_64, QAM_64 },
+ { DVBFE_ATSC_MOD_QAM_256, QAM_256 },
+ { DVBFE_ATSC_MOD_VSB_8, VSB_8 },
+ { DVBFE_ATSC_MOD_VSB_16, VSB_16 },
+ { DVBFE_ATSC_MOD_AUTO, QAM_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_dvbt_transmit_mode_to_kapi[][2] =
+{
+ { DVBFE_DVBT_TRANSMISSION_MODE_2K, TRANSMISSION_MODE_2K },
+ { DVBFE_DVBT_TRANSMISSION_MODE_8K, TRANSMISSION_MODE_8K },
+ { DVBFE_DVBT_TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_dvbt_bandwidth_to_kapi[][2] =
+{
+ { DVBFE_DVBT_BANDWIDTH_8_MHZ, BANDWIDTH_8_MHZ },
+ { DVBFE_DVBT_BANDWIDTH_7_MHZ, BANDWIDTH_7_MHZ },
+ { DVBFE_DVBT_BANDWIDTH_6_MHZ, BANDWIDTH_6_MHZ },
+ { DVBFE_DVBT_BANDWIDTH_AUTO, BANDWIDTH_AUTO },
+ { -1, -1 }
+};
+
+static int dvbfe_dvbt_guard_interval_to_kapi[][2] =
+{
+ { DVBFE_DVBT_GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_32},
+ { DVBFE_DVBT_GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_16},
+ { DVBFE_DVBT_GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_8},
+ { DVBFE_DVBT_GUARD_INTERVAL_1_4, GUARD_INTERVAL_1_4},
+ { DVBFE_DVBT_GUARD_INTERVAL_AUTO, GUARD_INTERVAL_AUTO},
+ { -1, -1 }
+};
+
+static int dvbfe_dvbt_hierarchy_to_kapi[][2] =
+{
+ { DVBFE_DVBT_HIERARCHY_NONE, HIERARCHY_NONE },
+ { DVBFE_DVBT_HIERARCHY_1, HIERARCHY_1 },
+ { DVBFE_DVBT_HIERARCHY_2, HIERARCHY_2 },
+ { DVBFE_DVBT_HIERARCHY_4, HIERARCHY_4 },
+ { DVBFE_DVBT_HIERARCHY_AUTO, HIERARCHY_AUTO },
+ { -1, -1 }
+};
+
+
+static int lookupval(int val, int reverse, int table[][2])
+{
+ int i =0;
+
+ while(table[i][0] != -1) {
+ if (!reverse) {
+ if (val == table[i][0]) {
+ return table[i][1];
+ }
+ } else {
+ if (val == table[i][1]) {
+ return table[i][0];
+ }
+ }
+ i++;
+ }
+
+ return -1;
+}
+
+
+struct dvbfe_handle {
+ int fd;
+ enum dvbfe_type type;
+ char *name;
+};
+
+struct dvbfe_handle *dvbfe_open(int adapter, int frontend, int readonly)
+{
+ char filename[PATH_MAX+1];
+ struct dvbfe_handle *fehandle;
+ int fd;
+ struct dvb_frontend_info info;
+
+ // flags
+ int flags = O_RDWR;
+ if (readonly) {
+ flags = O_RDONLY;
+ }
+
+ // open it (try normal /dev structure first)
+ sprintf(filename, "/dev/dvb/adapter%i/frontend%i", adapter, frontend);
+ if ((fd = open(filename, flags)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.frontend%i", adapter, frontend);
+ if ((fd = open(filename, flags)) < 0) {
+ return NULL;
+ }
+ }
+
+ // determine fe type
+ if (ioctl(fd, FE_GET_INFO, &info)) {
+ close(fd);
+ return NULL;
+ }
+
+ // setup structure
+ fehandle = (struct dvbfe_handle*) malloc(sizeof(struct dvbfe_handle));
+ memset(fehandle, 0, sizeof(struct dvbfe_handle));
+ fehandle->fd = fd;
+ switch(info.type) {
+ case FE_QPSK:
+ fehandle->type = DVBFE_TYPE_DVBS;
+ break;
+
+ case FE_QAM:
+ fehandle->type = DVBFE_TYPE_DVBC;
+ break;
+
+ case FE_OFDM:
+ fehandle->type = DVBFE_TYPE_DVBT;
+ break;
+
+ case FE_ATSC:
+ fehandle->type = DVBFE_TYPE_ATSC;
+ break;
+ }
+ fehandle->name = strndup(info.name, sizeof(info.name));
+
+ // done
+ return fehandle;
+}
+
+void dvbfe_close(struct dvbfe_handle *fehandle)
+{
+ close(fehandle->fd);
+ free(fehandle->name);
+ free(fehandle);
+}
+
+extern int dvbfe_get_info(struct dvbfe_handle *fehandle,
+ enum dvbfe_info_mask querymask,
+ struct dvbfe_info *result,
+ enum dvbfe_info_querytype querytype,
+ int timeout)
+{
+ int returnval = 0;
+ struct dvb_frontend_event kevent;
+ int ok = 0;
+
+ result->name = fehandle->name;
+ result->type = fehandle->type;
+
+ switch(querytype) {
+ case DVBFE_INFO_QUERYTYPE_IMMEDIATE:
+ if (querymask & DVBFE_INFO_LOCKSTATUS) {
+ if (!ioctl(fehandle->fd, FE_READ_STATUS, &kevent.status)) {
+ returnval |= DVBFE_INFO_LOCKSTATUS;
+ }
+ }
+ if (querymask & DVBFE_INFO_FEPARAMS) {
+ if (!ioctl(fehandle->fd, FE_GET_FRONTEND, &kevent.parameters)) {
+ returnval |= DVBFE_INFO_FEPARAMS;
+ }
+ }
+ break;
+
+ case DVBFE_INFO_QUERYTYPE_LOCKCHANGE:
+ {
+ struct pollfd pollfd;
+ pollfd.fd = fehandle->fd;
+ pollfd.events = POLLIN | POLLERR;
+
+ ok = 1;
+ if (poll(&pollfd, 1, timeout) < 0)
+ ok = 0;
+ if (pollfd.revents & POLLERR)
+ ok = 0;
+ if (!(pollfd.revents & POLLIN))
+ ok = 0;
+ }
+
+ if (ok &&
+ ((querymask & DVBFE_INFO_LOCKSTATUS) ||
+ (querymask & DVBFE_INFO_FEPARAMS))) {
+ if (!ioctl(fehandle->fd, FE_GET_EVENT, &kevent)) {
+ if (querymask & DVBFE_INFO_LOCKSTATUS)
+ returnval |= DVBFE_INFO_LOCKSTATUS;
+ if (querymask & DVBFE_INFO_FEPARAMS)
+ returnval |= DVBFE_INFO_FEPARAMS;
+ }
+ }
+ break;
+ }
+
+ if (returnval & DVBFE_INFO_LOCKSTATUS) {
+ result->signal = kevent.status & FE_HAS_SIGNAL ? 1 : 0;
+ result->carrier = kevent.status & FE_HAS_CARRIER ? 1 : 0;
+ result->viterbi = kevent.status & FE_HAS_VITERBI ? 1 : 0;
+ result->sync = kevent.status & FE_HAS_SYNC ? 1 : 0;
+ result->lock = kevent.status & FE_HAS_LOCK ? 1 : 0;
+ }
+
+ if (returnval & DVBFE_INFO_FEPARAMS) {
+ result->feparams.frequency = kevent.parameters.frequency;
+ result->feparams.inversion = lookupval(kevent.parameters.inversion, 1, dvbfe_spectral_inversion_to_kapi);
+ switch(fehandle->type) {
+ case FE_QPSK:
+ result->feparams.u.dvbs.symbol_rate = kevent.parameters.u.qpsk.symbol_rate;
+ result->feparams.u.dvbs.fec_inner =
+ lookupval(kevent.parameters.u.qpsk.fec_inner, 1, dvbfe_code_rate_to_kapi);
+ break;
+
+ case FE_QAM:
+ result->feparams.u.dvbc.symbol_rate = kevent.parameters.u.qam.symbol_rate;
+ result->feparams.u.dvbc.fec_inner =
+ lookupval(kevent.parameters.u.qam.fec_inner, 1, dvbfe_code_rate_to_kapi);
+ result->feparams.u.dvbc.modulation =
+ lookupval(kevent.parameters.u.qam.modulation, 1, dvbfe_dvbc_mod_to_kapi);
+ break;
+
+ case FE_OFDM:
+ result->feparams.u.dvbt.bandwidth =
+ lookupval(kevent.parameters.u.ofdm.bandwidth, 1, dvbfe_dvbt_bandwidth_to_kapi);
+ result->feparams.u.dvbt.code_rate_HP =
+ lookupval(kevent.parameters.u.ofdm.code_rate_HP, 1, dvbfe_code_rate_to_kapi);
+ result->feparams.u.dvbt.code_rate_LP =
+ lookupval(kevent.parameters.u.ofdm.code_rate_LP, 1, dvbfe_code_rate_to_kapi);
+ result->feparams.u.dvbt.constellation =
+ lookupval(kevent.parameters.u.ofdm.constellation, 1, dvbfe_dvbt_const_to_kapi);
+ result->feparams.u.dvbt.transmission_mode =
+ lookupval(kevent.parameters.u.ofdm.transmission_mode, 1, dvbfe_dvbt_transmit_mode_to_kapi);
+ result->feparams.u.dvbt.guard_interval =
+ lookupval(kevent.parameters.u.ofdm.guard_interval, 1, dvbfe_dvbt_guard_interval_to_kapi);
+ result->feparams.u.dvbt.hierarchy_information =
+ lookupval(kevent.parameters.u.ofdm.hierarchy_information, 1, dvbfe_dvbt_hierarchy_to_kapi);
+ break;
+
+ case FE_ATSC:
+ result->feparams.u.atsc.modulation =
+ lookupval(kevent.parameters.u.vsb.modulation, 1, dvbfe_atsc_mod_to_kapi);
+ break;
+ }
+ }
+
+ if (querymask & DVBFE_INFO_BER) {
+ if (!ioctl(fehandle->fd, FE_READ_BER, &result->ber))
+ returnval |= DVBFE_INFO_BER;
+ }
+ if (querymask & DVBFE_INFO_SIGNAL_STRENGTH) {
+ if (!ioctl(fehandle->fd, FE_READ_SIGNAL_STRENGTH, &result->signal_strength))
+ returnval |= DVBFE_INFO_SIGNAL_STRENGTH;
+ }
+ if (querymask & DVBFE_INFO_SNR) {
+ if (!ioctl(fehandle->fd, FE_READ_SNR, &result->snr))
+ returnval |= DVBFE_INFO_SNR;
+ }
+ if (querymask & DVBFE_INFO_UNCORRECTED_BLOCKS) {
+ if (!ioctl(fehandle->fd, FE_READ_UNCORRECTED_BLOCKS, &result->ucblocks))
+ returnval |= DVBFE_INFO_UNCORRECTED_BLOCKS;
+ }
+
+ // done
+ return returnval;
+}
+
+int dvbfe_set(struct dvbfe_handle *fehandle,
+ struct dvbfe_parameters *params,
+ int timeout)
+{
+ struct dvb_frontend_parameters kparams;
+ int res;
+ struct timeval endtime;
+ fe_status_t status;
+
+ kparams.frequency = params->frequency;
+ kparams.inversion = lookupval(params->inversion, 0, dvbfe_spectral_inversion_to_kapi);
+ switch(fehandle->type) {
+ case FE_QPSK:
+ kparams.u.qpsk.symbol_rate = params->u.dvbs.symbol_rate;
+ kparams.u.qpsk.fec_inner = lookupval(params->u.dvbs.fec_inner, 0, dvbfe_code_rate_to_kapi);
+ break;
+
+ case FE_QAM:
+ kparams.u.qam.symbol_rate = params->u.dvbc.symbol_rate;
+ kparams.u.qam.fec_inner = lookupval(params->u.dvbc.fec_inner, 0, dvbfe_code_rate_to_kapi);
+ kparams.u.qam.modulation = lookupval(params->u.dvbc.modulation, 0, dvbfe_dvbc_mod_to_kapi);
+ break;
+
+ case FE_OFDM:
+ kparams.u.ofdm.bandwidth = lookupval(params->u.dvbt.bandwidth, 0, dvbfe_dvbt_bandwidth_to_kapi);
+ kparams.u.ofdm.code_rate_HP = lookupval(params->u.dvbt.code_rate_HP, 0, dvbfe_code_rate_to_kapi);
+ kparams.u.ofdm.code_rate_LP = lookupval(params->u.dvbt.code_rate_LP, 0, dvbfe_code_rate_to_kapi);
+ kparams.u.ofdm.constellation = lookupval(params->u.dvbt.constellation, 0, dvbfe_dvbt_const_to_kapi);
+ kparams.u.ofdm.transmission_mode =
+ lookupval(params->u.dvbt.transmission_mode, 0, dvbfe_dvbt_transmit_mode_to_kapi);
+ kparams.u.ofdm.guard_interval =
+ lookupval(params->u.dvbt.guard_interval, 0, dvbfe_dvbt_guard_interval_to_kapi);
+ kparams.u.ofdm.hierarchy_information =
+ lookupval(params->u.dvbt.hierarchy_information, 0, dvbfe_dvbt_hierarchy_to_kapi);
+ break;
+
+ case FE_ATSC:
+ kparams.u.vsb.modulation = lookupval(params->u.atsc.modulation, 0, dvbfe_atsc_mod_to_kapi);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ // set it and check for error
+ res = ioctl(fehandle->fd, FE_SET_FRONTEND, &kparams);
+ if (res)
+ return res;
+
+ // 0 => return immediately
+ if (timeout == 0) {
+ return 0;
+ }
+
+ /* calculate timeout */
+ if (timeout > 0) {
+ gettimeofday(&endtime, NULL);
+ timeout *= 1000;
+ endtime.tv_sec += timeout / 1000000;
+ endtime.tv_usec += timeout % 1000000;
+ }
+
+ /* wait for a lock */
+ while(1) {
+ /* has it locked? */
+ if (!ioctl(fehandle->fd, FE_READ_STATUS, &status)) {
+ if (status & FE_HAS_LOCK) {
+ break;
+ }
+ }
+
+ /* check for timeout */
+ if (timeout > 0) {
+ struct timeval curtime;
+ gettimeofday(&curtime, NULL);
+ if ((curtime.tv_sec > endtime.tv_sec) ||
+ ((curtime.tv_sec == endtime.tv_sec) && (curtime.tv_usec >= endtime.tv_usec))) {
+ break;
+ }
+ }
+
+ /* delay for a bit */
+ usleep(100000);
+ }
+
+ /* exit */
+ if (status & FE_HAS_LOCK)
+ return 0;
+ return -ETIMEDOUT;
+}
+
+int dvbfe_get_pollfd(struct dvbfe_handle *handle)
+{
+ return handle->fd;
+}
+
+int dvbfe_set_22k_tone(struct dvbfe_handle *fehandle, enum dvbfe_sec_tone_mode tone)
+{
+ int ret = 0;
+
+ switch (tone) {
+ case DVBFE_SEC_TONE_OFF:
+ ret = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_OFF);
+ break;
+ case DVBFE_SEC_TONE_ON:
+ ret = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_ON);
+ break;
+ default:
+ print(verbose, ERROR, 1, "Invalid command !");
+ break;
+ }
+ if (ret == -1)
+ print(verbose, ERROR, 1, "IOCTL failed !");
+
+ return ret;
+}
+
+int dvbfe_set_tone_data_burst(struct dvbfe_handle *fehandle, enum dvbfe_sec_mini_cmd minicmd)
+{
+ int ret = 0;
+
+ switch (minicmd) {
+ case DVBFE_SEC_MINI_A:
+ ret = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_A);
+ break;
+ case DVBFE_SEC_MINI_B:
+ ret = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_B);
+ break;
+ default:
+ print(verbose, ERROR, 1, "Invalid command");
+ break;
+ }
+ if (ret == -1)
+ print(verbose, ERROR, 1, "IOCTL failed");
+
+ return ret;
+}
+
+int dvbfe_set_voltage(struct dvbfe_handle *fehandle, enum dvbfe_sec_voltage voltage)
+{
+ int ret = 0;
+
+ switch (voltage) {
+ case DVBFE_SEC_VOLTAGE_OFF:
+ ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF);
+ break;
+ case DVBFE_SEC_VOLTAGE_13:
+ ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13);
+ break;
+ case DVBFE_SEC_VOLTAGE_18:
+ ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18);
+ break;
+ default:
+ print(verbose, ERROR, 1, "Invalid command");
+ break;
+ }
+ if (ret == -1)
+ print(verbose, ERROR, 1, "IOCTL failed");
+
+ return ret;
+}
+
+int dvbfe_set_high_lnb_voltage(struct dvbfe_handle *fehandle, int on)
+{
+ switch (on) {
+ case 0:
+ ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 0);
+ break;
+ default:
+ ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 1);
+ break;
+ }
+ return 0;
+}
+
+int dvbfe_do_dishnetworks_legacy_command(struct dvbfe_handle *fehandle, unsigned int cmd)
+{
+ int ret = 0;
+
+ ret = ioctl(fehandle->fd, FE_DISHNETWORK_SEND_LEGACY_CMD, cmd);
+ if (ret == -1)
+ print(verbose, ERROR, 1, "IOCTL failed");
+
+ return ret;
+}
+
+int dvbfe_do_diseqc_command(struct dvbfe_handle *fehandle, uint8_t *data, uint8_t len)
+{
+ int ret = 0;
+ struct dvb_diseqc_master_cmd diseqc_message;
+
+ if (len > 6)
+ return -EINVAL;
+
+ diseqc_message.msg_len = len;
+ memcpy(diseqc_message.msg, data, len);
+
+ ret = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &diseqc_message);
+ if (ret == -1)
+ print(verbose, ERROR, 1, "IOCTL failed");
+
+ return ret;
+}
+
+int dvbfe_diseqc_read(struct dvbfe_handle *fehandle, int timeout, unsigned char *buf, unsigned int len)
+{
+ struct dvb_diseqc_slave_reply reply;
+ int result;
+
+ if (len > 4)
+ len = 4;
+
+ reply.timeout = timeout;
+ reply.msg_len = len;
+
+ if ((result = ioctl(fehandle->fd, FE_DISEQC_RECV_SLAVE_REPLY, reply)) != 0)
+ return result;
+
+ if (reply.msg_len < len)
+ len = reply.msg_len;
+ memcpy(buf, reply.msg, len);
+
+ return len;
+}
diff --git a/lib/libdvbapi/dvbfe.h b/lib/libdvbapi/dvbfe.h
new file mode 100644
index 0000000..69cb05b
--- /dev/null
+++ b/lib/libdvbapi/dvbfe.h
@@ -0,0 +1,333 @@
+/*
+ * libdvbfe - a DVB frontend library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LIBDVBFE_H
+#define LIBDVBFE_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * The types of frontend we support.
+ */
+enum dvbfe_type {
+ DVBFE_TYPE_DVBS,
+ DVBFE_TYPE_DVBC,
+ DVBFE_TYPE_DVBT,
+ DVBFE_TYPE_ATSC,
+};
+
+enum dvbfe_spectral_inversion {
+ DVBFE_INVERSION_OFF,
+ DVBFE_INVERSION_ON,
+ DVBFE_INVERSION_AUTO
+};
+
+enum dvbfe_code_rate {
+ DVBFE_FEC_NONE,
+ DVBFE_FEC_1_2,
+ DVBFE_FEC_2_3,
+ DVBFE_FEC_3_4,
+ DVBFE_FEC_4_5,
+ DVBFE_FEC_5_6,
+ DVBFE_FEC_6_7,
+ DVBFE_FEC_7_8,
+ DVBFE_FEC_8_9,
+ DVBFE_FEC_AUTO
+};
+
+enum dvbfe_dvbt_const {
+ DVBFE_DVBT_CONST_QPSK,
+ DVBFE_DVBT_CONST_QAM_16,
+ DVBFE_DVBT_CONST_QAM_32,
+ DVBFE_DVBT_CONST_QAM_64,
+ DVBFE_DVBT_CONST_QAM_128,
+ DVBFE_DVBT_CONST_QAM_256,
+ DVBFE_DVBT_CONST_AUTO
+};
+
+enum dvbfe_dvbc_mod {
+ DVBFE_DVBC_MOD_QAM_16,
+ DVBFE_DVBC_MOD_QAM_32,
+ DVBFE_DVBC_MOD_QAM_64,
+ DVBFE_DVBC_MOD_QAM_128,
+ DVBFE_DVBC_MOD_QAM_256,
+ DVBFE_DVBC_MOD_AUTO,
+};
+
+enum dvbfe_atsc_mod {
+ DVBFE_ATSC_MOD_QAM_64,
+ DVBFE_ATSC_MOD_QAM_256,
+ DVBFE_ATSC_MOD_VSB_8,
+ DVBFE_ATSC_MOD_VSB_16,
+ DVBFE_ATSC_MOD_AUTO
+};
+
+enum dvbfe_dvbt_transmit_mode {
+ DVBFE_DVBT_TRANSMISSION_MODE_2K,
+ DVBFE_DVBT_TRANSMISSION_MODE_8K,
+ DVBFE_DVBT_TRANSMISSION_MODE_AUTO
+};
+
+enum dvbfe_dvbt_bandwidth {
+ DVBFE_DVBT_BANDWIDTH_8_MHZ,
+ DVBFE_DVBT_BANDWIDTH_7_MHZ,
+ DVBFE_DVBT_BANDWIDTH_6_MHZ,
+ DVBFE_DVBT_BANDWIDTH_AUTO
+};
+
+enum dvbfe_dvbt_guard_interval {
+ DVBFE_DVBT_GUARD_INTERVAL_1_32,
+ DVBFE_DVBT_GUARD_INTERVAL_1_16,
+ DVBFE_DVBT_GUARD_INTERVAL_1_8,
+ DVBFE_DVBT_GUARD_INTERVAL_1_4,
+ DVBFE_DVBT_GUARD_INTERVAL_AUTO
+};
+
+enum dvbfe_dvbt_hierarchy {
+ DVBFE_DVBT_HIERARCHY_NONE,
+ DVBFE_DVBT_HIERARCHY_1,
+ DVBFE_DVBT_HIERARCHY_2,
+ DVBFE_DVBT_HIERARCHY_4,
+ DVBFE_DVBT_HIERARCHY_AUTO
+};
+
+/**
+ * Structure used to store and communicate frontend parameters.
+ */
+struct dvbfe_parameters {
+ uint32_t frequency;
+ enum dvbfe_spectral_inversion inversion;
+ union {
+ struct {
+ uint32_t symbol_rate;
+ enum dvbfe_code_rate fec_inner;
+ } dvbs;
+
+ struct {
+ uint32_t symbol_rate;
+ enum dvbfe_code_rate fec_inner;
+ enum dvbfe_dvbc_mod modulation;
+ } dvbc;
+
+ struct {
+ enum dvbfe_dvbt_bandwidth bandwidth;
+ enum dvbfe_code_rate code_rate_HP;
+ enum dvbfe_code_rate code_rate_LP;
+ enum dvbfe_dvbt_const constellation;
+ enum dvbfe_dvbt_transmit_mode transmission_mode;
+ enum dvbfe_dvbt_guard_interval guard_interval;
+ enum dvbfe_dvbt_hierarchy hierarchy_information;
+ } dvbt;
+
+ struct {
+ enum dvbfe_atsc_mod modulation;
+ } atsc;
+ } u;
+};
+
+enum dvbfe_sec_voltage {
+ DVBFE_SEC_VOLTAGE_13,
+ DVBFE_SEC_VOLTAGE_18,
+ DVBFE_SEC_VOLTAGE_OFF
+};
+
+enum dvbfe_sec_tone_mode {
+ DVBFE_SEC_TONE_ON,
+ DVBFE_SEC_TONE_OFF
+};
+
+enum dvbfe_sec_mini_cmd {
+ DVBFE_SEC_MINI_A,
+ DVBFE_SEC_MINI_B
+};
+
+/**
+ * Mask of values used in the dvbfe_get_info() call.
+ */
+enum dvbfe_info_mask {
+ DVBFE_INFO_LOCKSTATUS = 0x01,
+ DVBFE_INFO_FEPARAMS = 0x02,
+ DVBFE_INFO_BER = 0x04,
+ DVBFE_INFO_SIGNAL_STRENGTH = 0x08,
+ DVBFE_INFO_SNR = 0x10,
+ DVBFE_INFO_UNCORRECTED_BLOCKS = 0x20,
+};
+
+/**
+ * Structure containing values used by the dvbfe_get_info() call.
+ */
+struct dvbfe_info {
+ enum dvbfe_type type; /* always retrieved */
+ const char *name; /* always retrieved */
+ unsigned int signal : 1; /* } DVBFE_INFO_LOCKSTATUS */
+ unsigned int carrier : 1; /* } */
+ unsigned int viterbi : 1; /* } */
+ unsigned int sync : 1; /* } */
+ unsigned int lock : 1; /* } */
+ struct dvbfe_parameters feparams; /* DVBFE_INFO_FEPARAMS */
+ uint32_t ber; /* DVBFE_INFO_BER */
+ uint16_t signal_strength; /* DVBFE_INFO_SIGNAL_STRENGTH */
+ uint16_t snr; /* DVBFE_INFO_SNR */
+ uint32_t ucblocks; /* DVBFE_INFO_UNCORRECTED_BLOCKS */
+};
+
+/**
+ * Possible types of query used in dvbfe_get_info.
+ *
+ * DVBFE_INFO_QUERYTYPE_IMMEDIATE - interrogate frontend for most up to date values.
+ * DVBFE_INFO_QUERYTYPE_LOCKCHANGE - return details from queued lock status
+ * change events, or wait for one to occur
+ * if none are queued.
+ */
+enum dvbfe_info_querytype {
+ DVBFE_INFO_QUERYTYPE_IMMEDIATE,
+ DVBFE_INFO_QUERYTYPE_LOCKCHANGE,
+};
+
+
+/**
+ * Frontend handle datatype.
+ */
+struct dvbfe_handle;
+
+/**
+ * Open a DVB frontend.
+ *
+ * @param adapter DVB adapter ID.
+ * @param frontend Frontend ID of that adapter to open.
+ * @param readonly If 1, frontend will be opened in readonly mode only.
+ * @return A handle on success, or NULL on failure.
+ */
+extern struct dvbfe_handle *dvbfe_open(int adapter, int frontend, int readonly);
+
+/**
+ * Close a DVB frontend.
+ *
+ * @param fehandle Handle opened with dvbfe_open().
+ */
+extern void dvbfe_close(struct dvbfe_handle *handle);
+
+/**
+ * Set the frontend tuning parameters.
+ *
+ * Note: this function provides only the basic tuning operation; you might want to
+ * investigate dvbfe_set_sec() in sec.h for a unified device tuning operation.
+ *
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param params Params to set.
+ * @param timeout <0 => wait forever for lock. 0=>return immediately, >0=>
+ * number of milliseconds to wait for a lock.
+ * @return 0 on locked (or if timeout==0 and everything else worked), or
+ * nonzero on failure (including no lock).
+ */
+extern int dvbfe_set(struct dvbfe_handle *fehandle,
+ struct dvbfe_parameters *params,
+ int timeout);
+
+/**
+ * Retrieve information about the frontend.
+ *
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param querymask ORed bitmask of desired DVBFE_INFO_* values.
+ * @param result Where to put the retrieved results.
+ * @param querytype Type of query requested.
+ * @param timeout Timeout in ms to use if querytype==lockchange (0=>no timeout, <0=> wait forever).
+ * @return ORed bitmask of DVBFE_INFO_* indicating which values were read successfully.
+ */
+extern int dvbfe_get_info(struct dvbfe_handle *fehandle,
+ enum dvbfe_info_mask querymask,
+ struct dvbfe_info *result,
+ enum dvbfe_info_querytype querytype,
+ int timeout);
+
+/**
+ * Get a file descriptor for polling for lock status changes.
+ *
+ * @param fehandle Handle opened with dvbfe_open().
+ * @return FD for polling.
+ */
+extern int dvbfe_get_pollfd(struct dvbfe_handle *handle);
+
+/**
+ * Tone/Data Burst control
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param tone, SEC_TONE_ON/SEC_TONE_OFF
+ */
+extern int dvbfe_set_22k_tone(struct dvbfe_handle *handle, enum dvbfe_sec_tone_mode tone);
+
+/**
+ * 22khz Tone control
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param adapter, minicmd, SEC_MINI_A/SEC_MINI_B
+ */
+extern int dvbfe_set_tone_data_burst(struct dvbfe_handle *handle, enum dvbfe_sec_mini_cmd minicmd);
+
+/**
+ * Voltage control
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param polarization, SEC_VOLTAGE_13/SEC_VOLTAGE_18/SEC_VOLTAGE_OFF
+ */
+extern int dvbfe_set_voltage(struct dvbfe_handle *handle, enum dvbfe_sec_voltage voltage);
+
+/**
+ * High LNB voltage control (increases voltage by 1v to compensate for long cables)
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param on 1 to enable, 0 to disable.
+ */
+extern int dvbfe_set_high_lnb_voltage(struct dvbfe_handle *fehandle, int on);
+
+/**
+ * Send a legacy Dish Networks command
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param cmd, the command to send
+ */
+extern int dvbfe_do_dishnetworks_legacy_command(struct dvbfe_handle *handle, unsigned int cmd);
+
+/**
+ * Send a DiSEqC Command
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param data, a pointer to am array containing the data to be sent.
+ * @param len Length of data in bytes, max 6 bytes.
+ */
+extern int dvbfe_do_diseqc_command(struct dvbfe_handle *handle, uint8_t *data, uint8_t len);
+
+/**
+ * Read a DISEQC response from the frontend.
+ *
+ * @param fehandle Handle opened with dvbfe_open().
+ * @param timeout Timeout for DISEQC response.
+ * @param buf Buffer to store response in.
+ * @param len Number of bytes in buffer.
+ * @return >= 0 on success (number of received bytes), <0 on failure.
+ */
+extern int dvbfe_diseqc_read(struct dvbfe_handle *fehandle, int timeout, unsigned char *buf, unsigned int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBDVBFE_H
diff --git a/lib/libdvbapi/dvbnet.c b/lib/libdvbapi/dvbnet.c
new file mode 100644
index 0000000..f0f08f9
--- /dev/null
+++ b/lib/libdvbapi/dvbnet.c
@@ -0,0 +1,104 @@
+/*
+ * libdvbnet - a DVB network support library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/dvb/net.h>
+#include <errno.h>
+#include "dvbnet.h"
+
+int dvbnet_open(int adapter, int netdeviceid)
+{
+ char filename[PATH_MAX+1];
+ int fd;
+
+ sprintf(filename, "/dev/dvb/adapter%i/net%i", adapter, netdeviceid);
+ if ((fd = open(filename, O_RDWR)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.net%i", adapter, netdeviceid);
+ fd = open(filename, O_RDWR);
+ }
+
+ return fd;
+}
+
+int dvbnet_add_interface(int fd, uint16_t pid, enum dvbnet_encap encapsulation)
+{
+ struct dvb_net_if params;
+ int status;
+
+ memset(&params, 0, sizeof(params));
+ params.pid = pid;
+
+ switch(encapsulation) {
+ case DVBNET_ENCAP_MPE:
+ params.feedtype = DVB_NET_FEEDTYPE_MPE;
+ break;
+
+ case DVBNET_ENCAP_ULE:
+ params.feedtype = DVB_NET_FEEDTYPE_ULE;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ status = ioctl(fd, NET_ADD_IF, &params);
+ if (status < 0)
+ return status;
+ return params.if_num;
+}
+
+int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, enum dvbnet_encap *encapsulation)
+{
+ struct dvb_net_if info;
+ int res;
+
+ memset(&info, 0, sizeof(struct dvb_net_if));
+ info.if_num = ifnum;
+
+ if ((res = ioctl(fd, NET_GET_IF, &info)) < 0)
+ return res;
+
+ *pid = info.pid;
+ switch(info.feedtype) {
+ case DVB_NET_FEEDTYPE_MPE:
+ *encapsulation = DVBNET_ENCAP_MPE;
+ break;
+
+ case DVB_NET_FEEDTYPE_ULE:
+ *encapsulation = DVBNET_ENCAP_ULE;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int dvbnet_remove_interface(int fd, int ifnum)
+{
+ return ioctl(fd, NET_REMOVE_IF, ifnum);
+}
diff --git a/lib/libdvbapi/dvbnet.h b/lib/libdvbapi/dvbnet.h
new file mode 100644
index 0000000..287919f
--- /dev/null
+++ b/lib/libdvbapi/dvbnet.h
@@ -0,0 +1,87 @@
+/*
+ * libdvbnet - a DVB network support library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LIBDVBNET_H
+#define LIBDVBNET_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * Possible encapsulations of data.
+ */
+enum dvbnet_encap {
+ DVBNET_ENCAP_MPE,
+ DVBNET_ENCAP_ULE,
+};
+
+/**
+ * The maximum allowed number of dvb network devices per adapter netdevice.
+ */
+#define DVBNET_MAX_INTERFACES 10
+
+/**
+ * Open a DVB net interface.
+ *
+ * @param adapter DVB adapter ID.
+ * @param netdeviceid Network control interface of that adapter to open.
+ * @return A unix file descriptor on success, or -1 on failure.
+ */
+extern int dvbnet_open(int adapter, int netdeviceid);
+
+/**
+ * Create a new DVBNET interface.
+ *
+ * @param fd FD opened with libdvbnet_open().
+ * @param pid PID of the stream containing the network data.
+ * @param encapsulation Encapsulation type of the stream (one of DVBNET_ENCAP_*).
+ * @return Index of new interface on success, < 0 on failure.
+ */
+extern int dvbnet_add_interface(int fd, uint16_t pid, enum dvbnet_encap encapsulation);
+
+/**
+ * Get details of a DVBNET interface.
+ *
+ * @param fd FD opened with libdvbnet_open().
+ * @param ifnum Index of interface to retrieve.
+ * @param pid The PID of the interface.
+ * @param encapsulation The encapsulation of the interface (DVBNET_ENCAP_*).
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, enum dvbnet_encap *encapsulation);
+
+/**
+ * Remove a DVBNET interface.
+ *
+ * @param fd FD opened with libdvbnet_open().
+ * @param ifnum Index of interface to remove.
+ * @return 0 on success, nonzero on failure.
+ */
+extern int dvbnet_remove_interface(int fd, int ifnum);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBDVBNET_H
diff --git a/lib/libdvbapi/dvbvideo.c b/lib/libdvbapi/dvbvideo.c
new file mode 100644
index 0000000..f1ffbe8
--- /dev/null
+++ b/lib/libdvbapi/dvbvideo.c
@@ -0,0 +1,46 @@
+/*
+ * libdvbnet - a DVB network support library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/dvb/video.h>
+#include <errno.h>
+#include "dvbvideo.h"
+
+int dvbvideo_open(int adapter, int videodeviceid)
+{
+ char filename[PATH_MAX+1];
+ int fd;
+
+ sprintf(filename, "/dev/dvb/adapter%i/video%i", adapter, videodeviceid);
+ if ((fd = open(filename, O_RDWR)) < 0) {
+ // if that failed, try a flat /dev structure
+ sprintf(filename, "/dev/dvb%i.video%i", adapter, videodeviceid);
+ fd = open(filename, O_RDWR);
+ }
+
+ return fd;
+}
diff --git a/lib/libdvbapi/dvbvideo.h b/lib/libdvbapi/dvbvideo.h
new file mode 100644
index 0000000..cc49914
--- /dev/null
+++ b/lib/libdvbapi/dvbvideo.h
@@ -0,0 +1,46 @@
+/*
+ * libdvbnet - a DVB network support library
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LIBDVBVIDEO_H
+#define LIBDVBVIDEO_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * Open a DVB video device.
+ *
+ * @param adapter DVB adapter ID.
+ * @param videodeviceid Id of video device of that adapter to open.
+ * @return A unix file descriptor on success, or -1 on failure.
+ */
+extern int dvbvideo_open(int adapter, int videodeviceid);
+
+// FIXME: this is a stub library
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBDVBVIDEO_H
diff --git a/lib/libdvbcfg/Makefile b/lib/libdvbcfg/Makefile
new file mode 100644
index 0000000..5e5e365
--- /dev/null
+++ b/lib/libdvbcfg/Makefile
@@ -0,0 +1,18 @@
+# Makefile for linuxtv.org dvb-apps/lib/libdvbcfg
+
+includes = dvbcfg_zapchannel.h \
+ dvbcfg_scanfile.h
+
+objects = dvbcfg_zapchannel.o \
+ dvbcfg_scanfile.o \
+ dvbcfg_common.o
+
+lib_name = libdvbcfg
+
+CPPFLAGS += -I../../lib
+
+.PHONY: all
+
+all: library
+
+include ../../Make.rules
diff --git a/lib/libdvbcfg/dvbcfg_common.c b/lib/libdvbcfg/dvbcfg_common.c
new file mode 100644
index 0000000..1609e51
--- /dev/null
+++ b/lib/libdvbcfg/dvbcfg_common.c
@@ -0,0 +1,136 @@
+/*
+ * dvbcfg - support for linuxtv configuration files
+ * common functions
+ *
+ * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "dvbcfg_common.h"
+
+int dvbcfg_parse_int(char **text, char *tokens)
+{
+ char *start = *text;
+ char *stop = *text;
+ int value;
+
+ while (*stop != '\0') {
+ if (strchr(tokens, *stop) != NULL) {
+ *stop = '\0';
+ stop++;
+ break;
+ }
+ stop++;
+ }
+
+ if (sscanf(start, "%i", &value) == 1) {
+ *text = stop;
+ return value;
+ }
+
+ *text = NULL;
+ return -1;
+}
+
+int dvbcfg_parse_char(char **text, char *tokens)
+{
+ char *start = *text;
+ char *stop = *text;
+ char value;
+
+ while (*stop != '\0') {
+ if (strchr(tokens, *stop) != NULL) {
+ *stop = '\0';
+ stop++;
+ break;
+ }
+ stop++;
+ }
+
+ if (sscanf(start, "%c", &value) == 1) {
+ *text = stop;
+ return value;
+ }
+
+ *text = NULL;
+ return -1;
+}
+
+int dvbcfg_parse_setting(char **text, char *tokens, const struct dvbcfg_setting *settings)
+{
+ char *start = *text;
+ char *stop = *text;
+
+ while (*stop != '\0') {
+ if (strchr(tokens, *stop) != NULL) {
+ *stop = '\0';
+ stop++;
+ break;
+ }
+ stop++;
+ }
+
+ while (settings->name) {
+ if (strcmp(start, settings->name) == 0) {
+ *text = stop;
+ return settings->value;
+ }
+ settings++;
+ }
+
+ *text = NULL;
+ return -1;
+}
+
+void dvbcfg_parse_string(char **text, char *tokens, char *dest, unsigned long size)
+{
+ char *start = *text;
+ char *stop = *text;
+ unsigned long length;
+
+ while ((*stop != '\0') && (strchr(tokens, *stop) == NULL))
+ stop++;
+
+ length = (stop - start) + 1;
+
+ if (length <= size) {
+ if (strchr(tokens, *stop) != NULL) {
+ *stop = '\0';
+ *text = stop + 1;
+ } else
+ *text = stop;
+ memcpy(dest, start, length);
+ return;
+ }
+
+ *text = NULL;
+ return;
+}
+
+const char *dvbcfg_lookup_setting(unsigned int setting, const struct dvbcfg_setting *settings)
+{
+ while (settings->name) {
+ if (setting == settings->value)
+ return settings->name;
+ settings++;
+ }
+
+ return NULL;
+}
diff --git a/lib/libdvbcfg/dvbcfg_common.h b/lib/libdvbcfg/dvbcfg_common.h
new file mode 100644
index 0000000..2b5e876
--- /dev/null
+++ b/lib/libdvbcfg/dvbcfg_common.h
@@ -0,0 +1,37 @@
+/*
+ * dvbcfg - support for linuxtv configuration files
+ * common functions
+ *
+ * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DVBCFG_COMMON_H
+#define DVBCFG_COMMON_H 1
+
+struct dvbcfg_setting {
+ const char *name;
+ unsigned int value;
+};
+
+extern int dvbcfg_parse_int(char **text, char *tokens);
+extern int dvbcfg_parse_char(char **text, char *tokens);
+extern int dvbcfg_parse_setting(char **text, char *tokens, const struct dvbcfg_setting *settings);
+extern void dvbcfg_parse_string(char **text, char *tokens, char *dest, unsigned long size);
+extern const char *dvbcfg_lookup_setting(unsigned int setting, const struct dvbcfg_setting *settings);
+
+#endif
diff --git a/lib/libdvbcfg/dvbcfg_scanfile.c b/lib/libdvbcfg/dvbcfg_scanfile.c
new file mode 100644
index 0000000..ec305a4
--- /dev/null
+++ b/lib/libdvbcfg/dvbcfg_scanfile.c
@@ -0,0 +1,282 @@
+/*
+ * dvbcfg - support for linuxtv configuration files
+ * scan channel file support
+ *
+ * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define _GNU_SOURCE
+
+#include <malloc.h>
+#include <ctype.h>
+
+#include "dvbcfg_scanfile.h"
+#include "dvbcfg_common.h"
+
+static const struct dvbcfg_setting dvbcfg_fec_list[] = {
+ { "1/2", DVBFE_FEC_1_2 },
+ { "2/3", DVBFE_FEC_2_3 },
+ { "3/4", DVBFE_FEC_3_4 },
+ { "4/5", DVBFE_FEC_4_5 },
+ { "5/6", DVBFE_FEC_5_6 },
+ { "6/7", DVBFE_FEC_6_7 },
+ { "7/8", DVBFE_FEC_7_8 },
+ { "8/9", DVBFE_FEC_8_9 },
+ { "AUTO", DVBFE_FEC_AUTO },
+ { "NONE", DVBFE_FEC_NONE },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_dvbc_modulation_list[] = {
+ { "QAM16", DVBFE_DVBC_MOD_QAM_16 },
+ { "QAM32", DVBFE_DVBC_MOD_QAM_32 },
+ { "QAM64", DVBFE_DVBC_MOD_QAM_64 },
+ { "QAM128", DVBFE_DVBC_MOD_QAM_128 },
+ { "QAM256", DVBFE_DVBC_MOD_QAM_256 },
+ { "AUTO", DVBFE_DVBC_MOD_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_bandwidth_list[] = {
+ { "6MHz", DVBFE_DVBT_BANDWIDTH_6_MHZ },
+ { "7MHz", DVBFE_DVBT_BANDWIDTH_7_MHZ },
+ { "8MHz", DVBFE_DVBT_BANDWIDTH_8_MHZ },
+ { "AUTO", DVBFE_DVBT_BANDWIDTH_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_constellation_list[] = {
+ { "QAM16", DVBFE_DVBT_CONST_QAM_16 },
+ { "QAM32", DVBFE_DVBT_CONST_QAM_32 },
+ { "QAM64", DVBFE_DVBT_CONST_QAM_64 },
+ { "QAM128", DVBFE_DVBT_CONST_QAM_128 },
+ { "QAM256", DVBFE_DVBT_CONST_QAM_256 },
+ { "QPSK", DVBFE_DVBT_CONST_QPSK },
+ { "AUTO", DVBFE_DVBT_CONST_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_transmission_mode_list[] = {
+ { "2k", DVBFE_DVBT_TRANSMISSION_MODE_2K },
+ { "8k", DVBFE_DVBT_TRANSMISSION_MODE_8K },
+ { "AUTO", DVBFE_DVBT_TRANSMISSION_MODE_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_guard_interval_list[] = {
+ { "1/32", DVBFE_DVBT_GUARD_INTERVAL_1_32 },
+ { "1/16", DVBFE_DVBT_GUARD_INTERVAL_1_16 },
+ { "1/8", DVBFE_DVBT_GUARD_INTERVAL_1_8 },
+ { "1/4", DVBFE_DVBT_GUARD_INTERVAL_1_4 },
+ { "AUTO", DVBFE_DVBT_GUARD_INTERVAL_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_hierarchy_list[] = {
+ { "1", DVBFE_DVBT_HIERARCHY_1 },
+ { "2", DVBFE_DVBT_HIERARCHY_2 },
+ { "4", DVBFE_DVBT_HIERARCHY_4 },
+ { "AUTO", DVBFE_DVBT_HIERARCHY_AUTO },
+ { "NONE", DVBFE_DVBT_HIERARCHY_NONE },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_atsc_modulation_list[] = {
+ { "8VSB", DVBFE_ATSC_MOD_VSB_8 },
+ { "16VSB", DVBFE_ATSC_MOD_VSB_16 },
+ { "QAM64", DVBFE_ATSC_MOD_QAM_64 },
+ { "QAM256", DVBFE_ATSC_MOD_QAM_256 },
+ { NULL, 0 }
+};
+
+int dvbcfg_scanfile_parse(FILE *file, dvbcfg_scancallback callback, void *private_data)
+{
+ char *line_buf = NULL;
+ size_t line_size = 0;
+ int line_len = 0;
+ int ret_val = 0;
+
+ while ((line_len = getline(&line_buf, &line_size, file)) > 0) {
+ char *line_tmp = line_buf;
+ char *line_pos = line_buf;
+ struct dvbcfg_scanfile tmp;
+
+ /* remove newline and comments (started with hashes) */
+ while ((*line_tmp != '\0') && (*line_tmp != '\n') && (*line_tmp != '#'))
+ line_tmp++;
+ *line_tmp = '\0';
+
+ /* always use inversion auto */
+ tmp.fe_params.inversion = DVBFE_INVERSION_AUTO;
+
+ /* parse frontend type */
+ switch(dvbcfg_parse_char(&line_pos, " ")) {
+ case 'T':
+ tmp.fe_type = DVBFE_TYPE_DVBT;
+ break;
+ case 'C':
+ tmp.fe_type = DVBFE_TYPE_DVBC;
+ break;
+ case 'S':
+ tmp.fe_type = DVBFE_TYPE_DVBS;
+ break;
+ case 'A':
+ tmp.fe_type = DVBFE_TYPE_ATSC;
+ break;
+ default:
+ continue;
+ }
+
+ /* parse frontend specific settings */
+ switch (tmp.fe_type) {
+ case DVBFE_TYPE_ATSC:
+
+ /* parse frequency */
+ tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " ");
+ if (!line_pos)
+ continue;
+
+ /* modulation */
+ tmp.fe_params.u.atsc.modulation =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_atsc_modulation_list);
+ if (!line_pos)
+ continue;
+
+ break;
+
+ case DVBFE_TYPE_DVBC:
+
+ /* parse frequency */
+ tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " ");
+ if (!line_pos)
+ continue;
+
+ /* symbol rate */
+ tmp.fe_params.u.dvbc.symbol_rate = dvbcfg_parse_int(&line_pos, " ");
+ if (!line_pos)
+ continue;
+
+ /* fec */
+ tmp.fe_params.u.dvbc.fec_inner =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ /* modulation */
+ tmp.fe_params.u.dvbc.modulation =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_dvbc_modulation_list);
+ if (!line_pos)
+ continue;
+
+ break;
+
+ case DVBFE_TYPE_DVBS:
+
+ /* parse frequency */
+ tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " ");
+ if (!line_pos)
+ continue;
+
+ /* polarization */
+ tmp.polarization = tolower(dvbcfg_parse_char(&line_pos, " "));
+ if (!line_pos)
+ continue;
+ if ((tmp.polarization != 'h') &&
+ (tmp.polarization != 'v') &&
+ (tmp.polarization != 'l') &&
+ (tmp.polarization != 'r'))
+ continue;
+
+ /* symbol rate */
+ tmp.fe_params.u.dvbs.symbol_rate = dvbcfg_parse_int(&line_pos, " ");
+ if (!line_pos)
+ continue;
+
+ /* fec */
+ tmp.fe_params.u.dvbc.fec_inner =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ break;
+
+ case DVBFE_TYPE_DVBT:
+
+ /* parse frequency */
+ tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " ");
+ if (!line_pos)
+ continue;
+
+ /* bandwidth */
+ tmp.fe_params.u.dvbt.bandwidth =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_bandwidth_list);
+ if (!line_pos)
+ continue;
+
+ /* fec hp */
+ tmp.fe_params.u.dvbt.code_rate_HP =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ /* fec lp */
+ tmp.fe_params.u.dvbt.code_rate_LP =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ /* constellation */
+ tmp.fe_params.u.dvbt.constellation =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_constellation_list);
+ if (!line_pos)
+ continue;
+
+ /* transmission mode */
+ tmp.fe_params.u.dvbt.transmission_mode =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_transmission_mode_list);
+ if (!line_pos)
+ continue;
+
+ /* guard interval */
+ tmp.fe_params.u.dvbt.guard_interval =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_guard_interval_list);
+ if (!line_pos)
+ continue;
+
+ /* hierarchy */
+ tmp.fe_params.u.dvbt.hierarchy_information =
+ dvbcfg_parse_setting(&line_pos, " ", dvbcfg_hierarchy_list);
+ if (!line_pos)
+ continue;
+
+ break;
+ }
+
+ /* invoke callback */
+ if ((ret_val = callback(&tmp, private_data)) != 0) {
+ if (ret_val < 0)
+ ret_val = 0;
+ break;
+ }
+ }
+
+ if (line_buf)
+ free(line_buf);
+
+ return ret_val;
+}
diff --git a/lib/libdvbcfg/dvbcfg_scanfile.h b/lib/libdvbcfg/dvbcfg_scanfile.h
new file mode 100644
index 0000000..d7a20b1
--- /dev/null
+++ b/lib/libdvbcfg/dvbcfg_scanfile.h
@@ -0,0 +1,61 @@
+/*
+ * dvbcfg - support for linuxtv configuration files
+ * scan channel file support
+ *
+ * Copyright (C) 2006 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DVBCFG_SCANFILE_H
+#define DVBCFG_SCANFILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libdvbapi/dvbfe.h>
+#include <stdio.h>
+
+struct dvbcfg_scanfile {
+ enum dvbfe_type fe_type;
+ struct dvbfe_parameters fe_params;
+ char polarization; /* l,r,v,h - only used for dvb-s */
+};
+
+/**
+ * Callback used in dvbcfg_scanfile_parse()
+ *
+ * @param channel Selected channel
+ * @param private_data Private data for the callback
+ * @return 0 to continue, other values to stop (values > 0 are forwarded; see below)
+ */
+typedef int (*dvbcfg_scancallback)(struct dvbcfg_scanfile *channel, void *private_data);
+
+/**
+ * Parse a linuxtv scan file
+ *
+ * @param file Linuxtv scan file
+ * @param callback Callback called for each scan entry
+ * @param private_data Private data for the callback
+ * @return on success 0 or value from the callback if it's > 0, error code on failure
+ */
+extern int dvbcfg_scanfile_parse(FILE *file, dvbcfg_scancallback callback, void *private_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DVBCFG_SCANFILE_H */
diff --git a/lib/libdvbcfg/dvbcfg_zapchannel.c b/lib/libdvbcfg/dvbcfg_zapchannel.c
new file mode 100644
index 0000000..2c2605e
--- /dev/null
+++ b/lib/libdvbcfg/dvbcfg_zapchannel.c
@@ -0,0 +1,384 @@
+/*
+ * dvbcfg - support for linuxtv configuration files
+ * zap channel file support
+ *
+ * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define _GNU_SOURCE
+
+#include <malloc.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "dvbcfg_zapchannel.h"
+#include "dvbcfg_common.h"
+
+static const struct dvbcfg_setting dvbcfg_inversion_list[] = {
+ { "INVERSION_ON", DVBFE_INVERSION_ON },
+ { "INVERSION_OFF", DVBFE_INVERSION_OFF },
+ { "INVERSION_AUTO", DVBFE_INVERSION_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_fec_list[] = {
+ { "FEC_1_2", DVBFE_FEC_1_2 },
+ { "FEC_2_3", DVBFE_FEC_2_3 },
+ { "FEC_3_4", DVBFE_FEC_3_4 },
+ { "FEC_4_5", DVBFE_FEC_4_5 },
+ { "FEC_5_6", DVBFE_FEC_5_6 },
+ { "FEC_6_7", DVBFE_FEC_6_7 },
+ { "FEC_7_8", DVBFE_FEC_7_8 },
+ { "FEC_8_9", DVBFE_FEC_8_9 },
+ { "FEC_AUTO", DVBFE_FEC_AUTO },
+ { "FEC_NONE", DVBFE_FEC_NONE },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_dvbc_modulation_list[] = {
+ { "QAM_16", DVBFE_DVBC_MOD_QAM_16 },
+ { "QAM_32", DVBFE_DVBC_MOD_QAM_32 },
+ { "QAM_64", DVBFE_DVBC_MOD_QAM_64 },
+ { "QAM_128", DVBFE_DVBC_MOD_QAM_128 },
+ { "QAM_256", DVBFE_DVBC_MOD_QAM_256 },
+ { "QAM_AUTO", DVBFE_DVBC_MOD_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_bandwidth_list[] = {
+ { "BANDWIDTH_6_MHZ", DVBFE_DVBT_BANDWIDTH_6_MHZ },
+ { "BANDWIDTH_7_MHZ", DVBFE_DVBT_BANDWIDTH_7_MHZ },
+ { "BANDWIDTH_8_MHZ", DVBFE_DVBT_BANDWIDTH_8_MHZ },
+ { "BANDWIDTH_AUTO", DVBFE_DVBT_BANDWIDTH_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_constellation_list[] = {
+ { "QAM_16", DVBFE_DVBT_CONST_QAM_16 },
+ { "QAM_32", DVBFE_DVBT_CONST_QAM_32 },
+ { "QAM_64", DVBFE_DVBT_CONST_QAM_64 },
+ { "QAM_128", DVBFE_DVBT_CONST_QAM_128 },
+ { "QAM_256", DVBFE_DVBT_CONST_QAM_256 },
+ { "QPSK", DVBFE_DVBT_CONST_QPSK },
+ { "QAM_AUTO", DVBFE_DVBT_CONST_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_transmission_mode_list[] = {
+ { "TRANSMISSION_MODE_2K", DVBFE_DVBT_TRANSMISSION_MODE_2K },
+ { "TRANSMISSION_MODE_8K", DVBFE_DVBT_TRANSMISSION_MODE_8K },
+ { "TRANSMISSION_MODE_AUTO", DVBFE_DVBT_TRANSMISSION_MODE_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_guard_interval_list[] = {
+ { "GUARD_INTERVAL_1_32", DVBFE_DVBT_GUARD_INTERVAL_1_32 },
+ { "GUARD_INTERVAL_1_16", DVBFE_DVBT_GUARD_INTERVAL_1_16 },
+ { "GUARD_INTERVAL_1_8", DVBFE_DVBT_GUARD_INTERVAL_1_8 },
+ { "GUARD_INTERVAL_1_4", DVBFE_DVBT_GUARD_INTERVAL_1_4 },
+ { "GUARD_INTERVAL_AUTO", DVBFE_DVBT_GUARD_INTERVAL_AUTO },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_hierarchy_list[] = {
+ { "HIERARCHY_1", DVBFE_DVBT_HIERARCHY_1 },
+ { "HIERARCHY_2", DVBFE_DVBT_HIERARCHY_2 },
+ { "HIERARCHY_4", DVBFE_DVBT_HIERARCHY_4 },
+ { "HIERARCHY_AUTO", DVBFE_DVBT_HIERARCHY_AUTO },
+ { "HIERARCHY_NONE", DVBFE_DVBT_HIERARCHY_NONE },
+ { NULL, 0 }
+};
+
+static const struct dvbcfg_setting dvbcfg_atsc_modulation_list[] = {
+ { "8VSB", DVBFE_ATSC_MOD_VSB_8 },
+ { "16VSB", DVBFE_ATSC_MOD_VSB_16 },
+ { "QAM_64", DVBFE_ATSC_MOD_QAM_64 },
+ { "QAM_256", DVBFE_ATSC_MOD_QAM_256 },
+ { NULL, 0 }
+};
+
+int dvbcfg_zapchannel_parse(FILE *file, dvbcfg_zapcallback callback, void *private_data)
+{
+ char *line_buf = NULL;
+ size_t line_size = 0;
+ int line_len = 0;
+ int ret_val = 0;
+
+ while ((line_len = getline(&line_buf, &line_size, file)) > 0) {
+ char *line_tmp = line_buf;
+ char *line_pos = line_buf;
+ struct dvbcfg_zapchannel tmp;
+
+ /* remove newline and comments (started with hashes) */
+ while ((*line_tmp != '\0') && (*line_tmp != '\n') && (*line_tmp != '#'))
+ line_tmp++;
+ *line_tmp = '\0';
+
+ /* parse name */
+ dvbcfg_parse_string(&line_pos, ":", tmp.name, sizeof(tmp.name));
+ if (!line_pos)
+ continue;
+
+ /* parse frequency */
+ tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, ":");
+ if (!line_pos)
+ continue;
+
+ /* try to determine frontend type */
+ if (strstr(line_pos, ":FEC_")) {
+ if (strstr(line_pos, ":HIERARCHY_"))
+ tmp.fe_type = DVBFE_TYPE_DVBT;
+ else
+ tmp.fe_type = DVBFE_TYPE_DVBC;
+ } else {
+ if (strstr(line_pos, "VSB:") || strstr(line_pos, "QAM_"))
+ tmp.fe_type = DVBFE_TYPE_ATSC;
+ else
+ tmp.fe_type = DVBFE_TYPE_DVBS;
+ }
+
+ /* parse frontend specific settings */
+ switch (tmp.fe_type) {
+ case DVBFE_TYPE_ATSC:
+ /* inversion */
+ tmp.fe_params.inversion = DVBFE_INVERSION_AUTO;
+
+ /* modulation */
+ tmp.fe_params.u.atsc.modulation =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_atsc_modulation_list);
+ if (!line_pos)
+ continue;
+
+ break;
+
+ case DVBFE_TYPE_DVBC:
+ /* inversion */
+ tmp.fe_params.inversion =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_inversion_list);
+ if (!line_pos)
+ continue;
+
+ /* symbol rate */
+ tmp.fe_params.u.dvbc.symbol_rate = dvbcfg_parse_int(&line_pos, ":");
+ if (!line_pos)
+ continue;
+
+ /* fec */
+ tmp.fe_params.u.dvbc.fec_inner =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ /* modulation */
+ tmp.fe_params.u.dvbc.modulation =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_dvbc_modulation_list);
+ if (!line_pos)
+ continue;
+
+ break;
+
+ case DVBFE_TYPE_DVBS:
+ /* adjust frequency */
+ tmp.fe_params.frequency *= 1000;
+
+ /* inversion */
+ tmp.fe_params.inversion = DVBFE_INVERSION_AUTO;
+
+ /* fec */
+ tmp.fe_params.u.dvbs.fec_inner = DVBFE_FEC_AUTO;
+
+ /* polarization */
+ tmp.polarization = tolower(dvbcfg_parse_char(&line_pos, ":"));
+ if (!line_pos)
+ continue;
+ if ((tmp.polarization != 'h') &&
+ (tmp.polarization != 'v') &&
+ (tmp.polarization != 'l') &&
+ (tmp.polarization != 'r'))
+ continue;
+
+ /* satellite switch position */
+ tmp.diseqc_switch = dvbcfg_parse_int(&line_pos, ":");
+ if (!line_pos)
+ continue;
+
+ /* symbol rate */
+ tmp.fe_params.u.dvbs.symbol_rate =
+ dvbcfg_parse_int(&line_pos, ":") * 1000;
+ if (!line_pos)
+ continue;
+
+ break;
+
+ case DVBFE_TYPE_DVBT:
+ /* inversion */
+ tmp.fe_params.inversion =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_inversion_list);
+ if (!line_pos)
+ continue;
+
+ /* bandwidth */
+ tmp.fe_params.u.dvbt.bandwidth =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_bandwidth_list);
+ if (!line_pos)
+ continue;
+
+ /* fec hp */
+ tmp.fe_params.u.dvbt.code_rate_HP =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ /* fec lp */
+ tmp.fe_params.u.dvbt.code_rate_LP =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list);
+ if (!line_pos)
+ continue;
+
+ /* constellation */
+ tmp.fe_params.u.dvbt.constellation =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_constellation_list);
+ if (!line_pos)
+ continue;
+
+ /* transmission mode */
+ tmp.fe_params.u.dvbt.transmission_mode =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_transmission_mode_list);
+ if (!line_pos)
+ continue;
+
+ /* guard interval */
+ tmp.fe_params.u.dvbt.guard_interval =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_guard_interval_list);
+ if (!line_pos)
+ continue;
+
+ /* hierarchy */
+ tmp.fe_params.u.dvbt.hierarchy_information =
+ dvbcfg_parse_setting(&line_pos, ":", dvbcfg_hierarchy_list);
+ if (!line_pos)
+ continue;
+
+ break;
+ }
+
+ /* parse video and audio pids and service id */
+ tmp.video_pid = dvbcfg_parse_int(&line_pos, ":");
+ if (!line_pos)
+ continue;
+ tmp.audio_pid = dvbcfg_parse_int(&line_pos, ":");
+ if (!line_pos)
+ continue;
+ tmp.service_id = dvbcfg_parse_int(&line_pos, ":");
+ if (!line_pos) /* old files don't have a service id */
+ tmp.service_id = 0;
+
+ /* invoke callback */
+ if ((ret_val = callback(&tmp, private_data)) != 0) {
+ if (ret_val < 0)
+ ret_val = 0;
+ break;
+ }
+ }
+
+ if (line_buf)
+ free(line_buf);
+
+ return ret_val;
+}
+
+int dvbcfg_zapchannel_save(FILE *file, dvbcfg_zapcallback callback, void *private_data)
+{
+ int ret_val = 0;
+ struct dvbcfg_zapchannel tmp;
+
+ while ((ret_val = callback(&tmp, private_data)) == 0) {
+ /* name */
+ if ((ret_val = fprintf(file, "%s:", tmp.name)) < 0)
+ return ret_val;
+
+ /* frontend specific settings */
+ switch (tmp.fe_type) {
+ case DVBFE_TYPE_ATSC:
+ if ((ret_val = fprintf(file, "%i:%s:",
+ tmp.fe_params.frequency,
+ dvbcfg_lookup_setting(tmp.fe_params.u.atsc.modulation,
+ dvbcfg_atsc_modulation_list))) < 0)
+ return ret_val;
+
+ break;
+
+ case DVBFE_TYPE_DVBC:
+ if ((ret_val = fprintf(file, "%i:%s:%i:%s:%s:",
+ tmp.fe_params.frequency,
+ dvbcfg_lookup_setting(tmp.fe_params.inversion,
+ dvbcfg_inversion_list),
+ tmp.fe_params.u.dvbc.symbol_rate,
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbc.fec_inner,
+ dvbcfg_fec_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbc.modulation,
+ dvbcfg_dvbc_modulation_list))) < 0)
+ return ret_val;
+
+ break;
+
+ case DVBFE_TYPE_DVBS:
+ if ((ret_val = fprintf(file, "%i:%c:%i:%i:",
+ tmp.fe_params.frequency / 1000,
+ tolower(tmp.polarization),
+ tmp.diseqc_switch,
+ tmp.fe_params.u.dvbs.symbol_rate / 1000)) < 0)
+ return ret_val;
+
+ break;
+ case DVBFE_TYPE_DVBT:
+ if ((ret_val = fprintf(file, "%i:%s:%s:%s:%s:%s:%s:%s:%s:",
+ tmp.fe_params.frequency,
+ dvbcfg_lookup_setting(tmp.fe_params.inversion,
+ dvbcfg_inversion_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.bandwidth,
+ dvbcfg_bandwidth_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.code_rate_HP,
+ dvbcfg_fec_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.code_rate_LP,
+ dvbcfg_fec_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.constellation,
+ dvbcfg_constellation_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.transmission_mode,
+ dvbcfg_transmission_mode_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.guard_interval,
+ dvbcfg_guard_interval_list),
+ dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.hierarchy_information,
+ dvbcfg_hierarchy_list))) < 0)
+ return ret_val;
+
+ break;
+ }
+
+ /* video and audio pids and service id */
+ if ((ret_val = fprintf(file, "%i:%i:%i\n",
+ tmp.video_pid, tmp.audio_pid, tmp.service_id)) < 0)
+ return ret_val;
+
+ }
+
+ if (ret_val < 0)
+ ret_val = 0;
+
+ return ret_val;
+}
diff --git a/lib/libdvbcfg/dvbcfg_zapchannel.h b/lib/libdvbcfg/dvbcfg_zapchannel.h
new file mode 100644
index 0000000..67ec62e
--- /dev/null
+++ b/lib/libdvbcfg/dvbcfg_zapchannel.h
@@ -0,0 +1,77 @@
+/*
+ * dvbcfg - support for linuxtv configuration files
+ * zap channel file support
+ *
+ * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DVBCFG_ZAPCHANNEL_H
+#define DVBCFG_ZAPCHANNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libdvbapi/dvbfe.h>
+#include <stdio.h>
+
+struct dvbcfg_zapchannel {
+ char name[128];
+ int video_pid;
+ int audio_pid;
+ int service_id;
+ enum dvbfe_type fe_type;
+ struct dvbfe_parameters fe_params;
+ char polarization; /* l,r,v,h - only used for dvb-s */
+ int diseqc_switch; /* only used for dvb-s */
+};
+
+/**
+ * Callback used in dvbcfg_zapchannel_parse() and dvbcfg_zapchannel_save()
+ *
+ * @param channel Selected channel
+ * @param private_data Private data for the callback
+ * @return 0 to continue, other values to stop (values > 0 are forwarded; see below)
+ */
+typedef int (*dvbcfg_zapcallback)(struct dvbcfg_zapchannel *channel, void *private_data);
+
+/**
+ * Parse a linuxtv channel file
+ *
+ * @param file Linuxtv channel file
+ * @param callback Callback called for each channel
+ * @param private_data Private data for the callback
+ * @return on success 0 or value from the callback if it's > 0, error code on failure
+ */
+extern int dvbcfg_zapchannel_parse(FILE *file, dvbcfg_zapcallback callback, void *private_data);
+
+/**
+ * Save to a linuxtv channel file
+ *
+ * @param file Linuxtv channel file
+ * @param callback Callback called for each channel
+ * @param private_data Private data for the callback
+ * @return on success 0 or value from the callback if it's > 0, error code on failure
+ */
+extern int dvbcfg_zapchannel_save(FILE *file, dvbcfg_zapcallback callback, void *private_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DVBCFG_ZAPCHANNEL_H */
diff --git a/lib/libdvbcfg/zapchannel.txt b/lib/libdvbcfg/zapchannel.txt
new file mode 100644
index 0000000..cdfdb87
--- /dev/null
+++ b/lib/libdvbcfg/zapchannel.txt
@@ -0,0 +1,72 @@
+/**
+ * The zapchannel file format specifies tuning parameters for channels. Each line describes
+ * a single channel, and consists of multiple options separated by ':'. The exact
+ * format of each line depends on the DVB type of the channel (i.e. DVBS, DVBT, DVBC, or ATSC).
+ *
+ * Note: the lines have been split across multiple lines in the following due to length issues.
+ *
+ * The format for DVBT channels is:
+ *
+ * <name>:<frequency>:<inversion>:<bandwidth>:<fec_hp>:<fec_lp>:
+ * <constellation>:<transmission>:<guard_interval>:<hierarchy>:
+ * <video_pid>:<audio_pid>:<channel_number>
+ *
+ * name: name of the channel
+ * frequency: frequency in Hz
+ * inversion: one of INVERSION_OFF, INVERSION_ON, or INVERSION_AUTO.
+ * bandwidth: one of BANDWIDTH_6_MHZ, BANDWIDTH_7_MHZ, or BANDWIDTH_8_MHZ.
+ * fec_hp: FEC of the high priority stream, one of: FEC_1_2, FEC_2_3,
+ * FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8, FEC_8_9, or FEC_AUTO.
+ * fec_lp: FEC of the low priority stream, one of: FEC_1_2, FEC_2_3,
+ * FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8, FEC_8_9, FEC_AUTO, or FEC_NONE.
+ * constellation: one of QPSK, QAM_128, QAM_16, QAM_256, QAM_32, or QAM_64.
+ * transmission: one of TRANSMISSION_MODE_2K, or TRANSMISSION_MODE_8K.
+ * guard_interval: one of GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, or GUARD_INTERVAL_1_4.
+ * hierarchy: one of HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, or HIERARCHY_4.
+ * video_pid: PID of the video stream.
+ * audio_pid: PID of the audio stream.
+ * channel_number: Transport stream channel number of the program.
+ *
+ * DVBC:
+ *
+ * <name>:<frequency>:<inversion>:<symbol_rate>:<fec>:
+ * <modulation>:<video_pid>:<audio_pid>:<channel_number>
+ *
+ * name: name of the channel
+ * frequency: frequency in Hz
+ * inversion: one of INVERSION_OFF, INVERSION_ON, or INVERSION_AUTO.
+ * symbol_rate: Symbol rate of the channel in ksyms.
+ * fec: One of: FEC_1_2, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7,
+ * FEC_7_8, FEC_8_9, or FEC_AUTO.
+ * modulation: one of QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO.
+ * video_pid: PID of the video stream.
+ * audio_pid: PID of the audio stream.
+ * channel_number: Transport stream channel number of the program.
+ *
+ * DVBS:
+ *
+ * <name>:<frequency>:<polarization>:<satellite_switches>:<symbol_rate>:<video_pid>:<audio_pid>:<channel_number>
+ *
+ * name: name of the channel
+ * frequency: frequency in kHz
+ * polarization: one of H,V,L, or R.
+ * satellite_switches: Treated as a 2 bit value controlling switches in SEC equipment:
+ * bit 0: controls "satellite switch", 0: A, 1: B
+ * bit 1: controls "switch option", 0: A, 1: B
+ * symbol_rate: Symbol rate of the channel in ksyms.
+ * video_pid: PID of the video stream.
+ * audio_pid: PID of the audio stream.
+ * channel_number: Transport stream channel number of the program.
+ *
+ * ATSC:
+ *
+ * <name>:<frequency>:<inversion>:<modulation>:<video_pid>:<audio_pid>:<channel_number>
+ *
+ * name: name of the channel
+ * frequency: frequency in GHz
+ * inversion: one of INVERSION_OFF, INVERSION_ON, or INVERSION_AUTO.
+ * modulation: one of 8VSB, 16VSB, QAM_64, or QAM_256.
+ * video_pid: PID of the video stream.
+ * audio_pid: PID of the audio stream.
+ * channel_number: Transport stream channel number of the program.
+ */
diff --git a/lib/libdvben50221/Makefile b/lib/libdvben50221/Makefile
new file mode 100644
index 0000000..797ea2a
--- /dev/null
+++ b/lib/libdvben50221/Makefile
@@ -0,0 +1,49 @@
+# Makefile for linuxtv.org dvb-apps/lib/libdvben50221
+
+includes = asn_1.h \
+ en50221_app_ai.h \
+ en50221_app_auth.h \
+ en50221_app_ca.h \
+ en50221_app_datetime.h \
+ en50221_app_dvb.h \
+ en50221_app_epg.h \
+ en50221_app_lowspeed.h \
+ en50221_app_mmi.h \
+ en50221_app_rm.h \
+ en50221_app_smartcard.h \
+ en50221_app_tags.h \
+ en50221_app_teletext.h \
+ en50221_app_utils.h \
+ en50221_errno.h \
+ en50221_session.h \
+ en50221_stdcam.h \
+ en50221_transport.h
+
+objects = asn_1.o \
+ en50221_app_ai.o \
+ en50221_app_auth.o \
+ en50221_app_ca.o \
+ en50221_app_datetime.o \
+ en50221_app_dvb.o \
+ en50221_app_epg.o \
+ en50221_app_lowspeed.o \
+ en50221_app_mmi.o \
+ en50221_app_rm.o \
+ en50221_app_smartcard.o \
+ en50221_app_teletext.o \
+ en50221_app_utils.o \
+ en50221_session.o \
+ en50221_stdcam.o \
+ en50221_stdcam_hlci.o \
+ en50221_stdcam_llci.o \
+ en50221_transport.o
+
+lib_name = libdvben50221
+
+CPPFLAGS += -I../../lib -DLOG_LEVEL=1 # FIXME
+
+.PHONY: all
+
+all: library
+
+include ../../Make.rules
diff --git a/lib/libdvben50221/asn_1.c b/lib/libdvben50221/asn_1.c
new file mode 100644
index 0000000..803eb60
--- /dev/null
+++ b/lib/libdvben50221/asn_1.c
@@ -0,0 +1,83 @@
+/*
+ ASN.1 routines, implementation for libdvben50221
+ an implementation for the High Level Common Interface
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include "asn_1.h"
+
+int asn_1_decode(uint16_t * length, uint8_t * asn_1_array,
+ uint32_t asn_1_array_len)
+{
+ uint8_t length_field;
+
+ if (asn_1_array_len < 1)
+ return -1;
+ length_field = asn_1_array[0];
+
+ if (length_field < 0x80) {
+ // there is only one word
+ *length = length_field & 0x7f;
+ return 1;
+ } else if (length_field == 0x81) {
+ if (asn_1_array_len < 2)
+ return -1;
+
+ *length = asn_1_array[1];
+ return 2;
+ } else if (length_field == 0x82) {
+ if (asn_1_array_len < 3)
+ return -1;
+
+ *length = (asn_1_array[1] << 8) | asn_1_array[2];
+ return 3;
+ }
+
+ return -1;
+}
+
+int asn_1_encode(uint16_t length, uint8_t * asn_1_array,
+ uint32_t asn_1_array_len)
+{
+ if (length < 0x80) {
+ if (asn_1_array_len < 1)
+ return -1;
+
+ asn_1_array[0] = length & 0x7f;
+ return 1;
+ } else if (length < 0x100) {
+ if (asn_1_array_len < 2)
+ return -1;
+
+ asn_1_array[0] = 0x81;
+ asn_1_array[1] = length;
+ return 2;
+ } else {
+ if (asn_1_array_len < 3)
+ return -1;
+
+ asn_1_array[0] = 0x82;
+ asn_1_array[1] = length >> 8;
+ asn_1_array[2] = length;
+ return 3;
+ }
+
+ // never reached
+}
diff --git a/lib/libdvben50221/asn_1.h b/lib/libdvben50221/asn_1.h
new file mode 100644
index 0000000..c8774db
--- /dev/null
+++ b/lib/libdvben50221/asn_1.h
@@ -0,0 +1,41 @@
+/*
+ ASN.1 routines, implementation for libdvben50221
+ an implementation for the High Level Common Interface
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __ASN_1_H__
+#define __ASN_1_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+
+int asn_1_decode(uint16_t * length, uint8_t * asn_1_array,
+ uint32_t asn_1_array_len);
+int asn_1_encode(uint16_t length, uint8_t * asn_1_array,
+ uint32_t asn_1_array_len);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_ai.c b/lib/libdvben50221/en50221_app_ai.c
new file mode 100644
index 0000000..b7ded66
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_ai.c
@@ -0,0 +1,191 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include "en50221_app_ai.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_ai {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_ai_callback callback;
+ void *callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_ai_parse_app_info(struct en50221_app_ai *ai,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+struct en50221_app_ai *en50221_app_ai_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_ai *ai = NULL;
+
+ // create structure and set it up
+ ai = malloc(sizeof(struct en50221_app_ai));
+ if (ai == NULL) {
+ return NULL;
+ }
+ ai->funcs = funcs;
+ ai->callback = NULL;
+
+ pthread_mutex_init(&ai->lock, NULL);
+
+ // done
+ return ai;
+}
+
+void en50221_app_ai_destroy(struct en50221_app_ai *ai)
+{
+ pthread_mutex_destroy(&ai->lock);
+ free(ai);
+}
+
+void en50221_app_ai_register_callback(struct en50221_app_ai *ai,
+ en50221_app_ai_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&ai->lock);
+ ai->callback = callback;
+ ai->callback_arg = arg;
+ pthread_mutex_unlock(&ai->lock);
+}
+
+int en50221_app_ai_enquiry(struct en50221_app_ai *ai,
+ uint16_t session_number)
+{
+ uint8_t data[4];
+
+ data[0] = (TAG_APP_INFO_ENQUIRY >> 16) & 0xFF;
+ data[1] = (TAG_APP_INFO_ENQUIRY >> 8) & 0xFF;
+ data[2] = TAG_APP_INFO_ENQUIRY & 0xFF;
+ data[3] = 0;
+
+ return ai->funcs->send_data(ai->funcs->arg, session_number, data, 4);
+}
+
+int en50221_app_ai_entermenu(struct en50221_app_ai *ai,
+ uint16_t session_number)
+{
+ uint8_t data[4];
+
+ data[0] = (TAG_ENTER_MENU >> 16) & 0xFF;
+ data[1] = (TAG_ENTER_MENU >> 8) & 0xFF;
+ data[2] = TAG_ENTER_MENU & 0xFF;
+ data[3] = 0;
+
+ return ai->funcs->send_data(ai->funcs->arg, session_number, data, 4);
+}
+
+int en50221_app_ai_message(struct en50221_app_ai *ai,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_APP_INFO:
+ return en50221_app_ai_parse_app_info(ai, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+
+
+
+
+static int en50221_app_ai_parse_app_info(struct en50221_app_ai *ai,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // parse the length field
+ int length_field_len;
+ uint16_t asn_data_length;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return -1;
+ }
+ // check it
+ if (asn_data_length < 6) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t *app_info = data + length_field_len;
+
+ // parse the fields
+ uint8_t application_type = app_info[0];
+ uint16_t application_manufacturer = (app_info[1] << 8) | app_info[2];
+ uint16_t manufacturer_code = (app_info[3] << 8) | app_info[4];
+ uint8_t menu_string_length = app_info[5];
+ uint8_t *menu_string = app_info + 6;
+
+ // check the menu_string_length
+ if (menu_string_length > (asn_data_length - 6)) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received bad menu string length - adjusting\n");
+ menu_string_length = asn_data_length - 6;
+ }
+ // tell the app
+ pthread_mutex_lock(&ai->lock);
+ en50221_app_ai_callback cb = ai->callback;
+ void *cb_arg = ai->callback_arg;
+ pthread_mutex_unlock(&ai->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ application_type, application_manufacturer,
+ manufacturer_code, menu_string_length,
+ menu_string);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_ai.h b/lib/libdvben50221/en50221_app_ai.h
new file mode 100644
index 0000000..18b5cd2
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_ai.h
@@ -0,0 +1,136 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_AI_H__
+#define __EN50221_APPLICATION_AI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_AI_RESOURCEID MKRID(2,1,1)
+
+#define APPLICATION_TYPE_CA 0x01
+#define APPLICATION_TYPE_EPG 0x02
+
+/**
+ * Type definition for application callback function - called when we receive
+ * an application info object.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Resource id concerned.
+ * @param application_type Type of application.
+ * @param application_manufacturer Manufacturer of application.
+ * @param manufacturer_code Manufacturer specific code.
+ * @param menu_string_length Length of menu string.
+ * @param menu_string The menu string itself.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_ai_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t application_type,
+ uint16_t application_manufacturer,
+ uint16_t manufacturer_code,
+ uint8_t menu_string_length,
+ uint8_t * menu_string);
+
+/**
+ * Opaque type representing an application information resource.
+ */
+struct en50221_app_ai;
+
+/**
+ * Create an instance of an application information resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_ai *en50221_app_ai_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of an application information resource.
+ *
+ * @param ai Instance to destroy.
+ */
+extern void en50221_app_ai_destroy(struct en50221_app_ai *ai);
+
+/**
+ * Register a callback for reception of application_info objects.
+ *
+ * @param ai Application information instance.
+ * @param callback Callback function.
+ * @param arg Private argument passed during calls to the callback.
+ */
+extern void en50221_app_ai_register_callback(struct en50221_app_ai *ai,
+ en50221_app_ai_callback,
+ void *arg);
+
+/**
+ * send a enquiry for the app_info provided by a module
+ *
+ * @param ai Application information instance.
+ * @param session_number Session to send on.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_ai_enquiry(struct en50221_app_ai *ai,
+ uint16_t session_number);
+
+/**
+ * send a enter_menu tag, this will make the application
+ * open a new MMI session to provide a Menu, or so.
+ *
+ * @param ai Application information instance.
+ * @param session_number Session to send on.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_ai_entermenu(struct en50221_app_ai *ai,
+ uint16_t session_number);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param ai Application information instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_ai_message(struct en50221_app_ai *ai,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_auth.c b/lib/libdvben50221/en50221_app_auth.c
new file mode 100644
index 0000000..a8902c1
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_auth.c
@@ -0,0 +1,180 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include "en50221_app_auth.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_auth {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_auth_request_callback callback;
+ void *callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_auth_parse_request(struct en50221_app_auth *private,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+struct en50221_app_auth *en50221_app_auth_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_auth *auth = NULL;
+
+ // create structure and set it up
+ auth = malloc(sizeof(struct en50221_app_auth));
+ if (auth == NULL) {
+ return NULL;
+ }
+ auth->funcs = funcs;
+ auth->callback = NULL;
+
+ pthread_mutex_init(&auth->lock, NULL);
+
+ // done
+ return auth;
+}
+
+void en50221_app_auth_destroy(struct en50221_app_auth *auth)
+{
+ pthread_mutex_destroy(&auth->lock);
+ free(auth);
+}
+
+void en50221_app_auth_register_request_callback(struct en50221_app_auth *auth,
+ en50221_app_auth_request_callback callback, void *arg)
+{
+ pthread_mutex_lock(&auth->lock);
+ auth->callback = callback;
+ auth->callback_arg = arg;
+ pthread_mutex_unlock(&auth->lock);
+}
+
+int en50221_app_auth_send(struct en50221_app_auth *auth,
+ uint16_t session_number,
+ uint16_t auth_protocol_id, uint8_t * auth_data,
+ uint32_t auth_data_length)
+{
+ uint8_t buf[10];
+
+ // the header
+ buf[0] = (TAG_AUTH_RESP >> 16) & 0xFF;
+ buf[1] = (TAG_AUTH_RESP >> 8) & 0xFF;
+ buf[2] = TAG_AUTH_RESP & 0xFF;
+
+ // encode the length field
+ int length_field_len;
+ if ((length_field_len = asn_1_encode(auth_data_length + 2, buf + 3, 3)) < 0) {
+ return -1;
+ }
+ // the phase_id
+ buf[3 + length_field_len] = auth_protocol_id >> 8;
+ buf[3 + length_field_len + 1] = auth_protocol_id;
+
+ // build the iovecs
+ struct iovec iov[2];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 3 + length_field_len + 2;
+ iov[1].iov_base = auth_data;
+ iov[1].iov_len = auth_data_length;
+
+ // sendit
+ return auth->funcs->send_datav(auth->funcs->arg, session_number,
+ iov, 2);
+}
+
+int en50221_app_auth_message(struct en50221_app_auth *auth,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_AUTH_REQ:
+ return en50221_app_auth_parse_request(auth, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+static int en50221_app_auth_parse_request(struct en50221_app_auth *auth,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length < 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t *auth_data = data + length_field_len;
+
+ // process it
+ uint16_t auth_protocol_id = (auth_data[0] << 8) | auth_data[1];
+
+ // tell the app
+ pthread_mutex_lock(&auth->lock);
+ en50221_app_auth_request_callback cb = auth->callback;
+ void *cb_arg = auth->callback_arg;
+ pthread_mutex_unlock(&auth->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ auth_protocol_id, auth_data + 2,
+ asn_data_length - 2);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_auth.h b/lib/libdvben50221/en50221_app_auth.h
new file mode 100644
index 0000000..2b1d2e7
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_auth.h
@@ -0,0 +1,123 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_auth_H__
+#define __EN50221_APPLICATION_auth_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_AUTH_RESOURCEID MKRID(16,1,1)
+
+/**
+ * Type definition for request - called when we receive a auth request from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param auth_protocol_id Auth protocol id.
+ * @param auth_data Data for the request.
+ * @param auth_data_lenghth Number of bytes.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_auth_request_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint16_t auth_protcol_id,
+ uint8_t *auth_data,
+ uint32_t auth_data_length);
+
+/**
+ * Opaque type representing a auth resource.
+ */
+struct en50221_app_auth;
+
+/**
+ * Create an instance of the auth resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_auth *en50221_app_auth_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the auth resource.
+ *
+ * @param auth Instance to destroy.
+ */
+extern void en50221_app_auth_destroy(struct en50221_app_auth *auth);
+
+/**
+ * Register the callback for when we receive a request.
+ *
+ * @param auth auth resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_auth_register_request_callback(struct en50221_app_auth *auth,
+ en50221_app_auth_request_callback callback,
+ void *arg);
+
+/**
+ * Send an auth response to the CAM.
+ *
+ * @param auth auth resource instance.
+ * @param session_number Session number to send it on.
+ * @param auth_protocol_id Auth protocol id.
+ * @param auth_data Auth data.
+ * @param auth_data_length Number of bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_auth_send(struct en50221_app_auth *auth,
+ uint16_t session_number,
+ uint16_t auth_protocol_id,
+ uint8_t *auth_data,
+ uint32_t auth_data_length);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param auth Authentication instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_auth_message(struct en50221_app_auth *auth,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_ca.c b/lib/libdvben50221/en50221_app_ca.c
new file mode 100644
index 0000000..22d4499
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_ca.c
@@ -0,0 +1,631 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include <libucsi/mpeg/descriptor.h>
+#include "en50221_app_ca.h"
+#include "asn_1.h"
+
+// tags supported by this resource
+#define TAG_CA_INFO_ENQUIRY 0x9f8030
+#define TAG_CA_INFO 0x9f8031
+#define TAG_CA_PMT 0x9f8032
+#define TAG_CA_PMT_REPLY 0x9f8033
+
+struct en50221_app_ca {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_ca_info_callback ca_info_callback;
+ void *ca_info_callback_arg;
+
+ en50221_app_ca_pmt_reply_callback ca_pmt_reply_callback;
+ void *ca_pmt_reply_callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+struct ca_pmt_descriptor {
+ uint8_t *descriptor;
+ uint16_t length;
+
+ struct ca_pmt_descriptor *next;
+};
+
+struct ca_pmt_stream {
+ uint8_t stream_type;
+ uint16_t pid;
+ struct ca_pmt_descriptor *descriptors;
+ uint32_t descriptors_length;
+ uint32_t descriptors_count;
+
+ struct ca_pmt_stream *next;
+};
+
+static int en50221_ca_extract_pmt_descriptors(struct mpeg_pmt_section *pmt,
+ struct ca_pmt_descriptor **outdescriptors);
+static int en50221_ca_extract_streams(struct mpeg_pmt_section *pmt,
+ struct ca_pmt_stream **outstreams);
+static void en50221_ca_try_move_pmt_descriptors(struct ca_pmt_descriptor **pmt_descriptors,
+ struct ca_pmt_stream **pmt_streams);
+static uint32_t en50221_ca_calculate_length(struct ca_pmt_descriptor *pmt_descriptors,
+ uint32_t *pmt_descriptors_length,
+ struct ca_pmt_stream *pmt_streams);
+static int en50221_app_ca_parse_info(struct en50221_app_ca *ca,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data, uint32_t data_length);
+static int en50221_app_ca_parse_reply(struct en50221_app_ca *ca,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+
+struct en50221_app_ca *en50221_app_ca_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_ca *ca = NULL;
+
+ // create structure and set it up
+ ca = malloc(sizeof(struct en50221_app_ca));
+ if (ca == NULL) {
+ return NULL;
+ }
+ ca->funcs = funcs;
+ ca->ca_info_callback = NULL;
+ ca->ca_pmt_reply_callback = NULL;
+
+ pthread_mutex_init(&ca->lock, NULL);
+
+ // done
+ return ca;
+}
+
+void en50221_app_ca_destroy(struct en50221_app_ca *ca)
+{
+ pthread_mutex_destroy(&ca->lock);
+ free(ca);
+}
+
+void en50221_app_ca_register_info_callback(struct en50221_app_ca *ca,
+ en50221_app_ca_info_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&ca->lock);
+ ca->ca_info_callback = callback;
+ ca->ca_info_callback_arg = arg;
+ pthread_mutex_unlock(&ca->lock);
+}
+
+void en50221_app_ca_register_pmt_reply_callback(struct en50221_app_ca *ca,
+ en50221_app_ca_pmt_reply_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&ca->lock);
+ ca->ca_pmt_reply_callback = callback;
+ ca->ca_pmt_reply_callback_arg = arg;
+ pthread_mutex_unlock(&ca->lock);
+}
+
+int en50221_app_ca_info_enq(struct en50221_app_ca *ca,
+ uint16_t session_number)
+{
+ uint8_t data[4];
+
+ data[0] = (TAG_CA_INFO_ENQUIRY >> 16) & 0xFF;
+ data[1] = (TAG_CA_INFO_ENQUIRY >> 8) & 0xFF;
+ data[2] = TAG_CA_INFO_ENQUIRY & 0xFF;
+ data[3] = 0;
+ return ca->funcs->send_data(ca->funcs->arg, session_number, data, 4);
+}
+
+int en50221_app_ca_pmt(struct en50221_app_ca *ca,
+ uint16_t session_number,
+ uint8_t * ca_pmt, uint32_t ca_pmt_length)
+{
+ uint8_t buf[10];
+
+ // set up the tag
+ buf[0] = (TAG_CA_PMT >> 16) & 0xFF;
+ buf[1] = (TAG_CA_PMT >> 8) & 0xFF;
+ buf[2] = TAG_CA_PMT & 0xFF;
+
+ // encode the length field
+ int length_field_len;
+ if ((length_field_len = asn_1_encode(ca_pmt_length, buf + 3, 3)) < 0) {
+ return -1;
+ }
+ // build the iovecs
+ struct iovec iov[2];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 3 + length_field_len;
+ iov[1].iov_base = ca_pmt;
+ iov[1].iov_len = ca_pmt_length;
+
+ // create the data and send it
+ return ca->funcs->send_datav(ca->funcs->arg, session_number, iov, 2);
+}
+
+int en50221_app_ca_message(struct en50221_app_ca *ca,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_CA_INFO:
+ return en50221_app_ca_parse_info(ca, slot_id,
+ session_number, data + 3,
+ data_length - 3);
+ case TAG_CA_PMT_REPLY:
+ return en50221_app_ca_parse_reply(ca, slot_id,
+ session_number, data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+int en50221_ca_format_pmt(struct mpeg_pmt_section *pmt, uint8_t * data,
+ uint32_t data_length, int move_ca_descriptors,
+ uint8_t ca_pmt_list_management,
+ uint8_t ca_pmt_cmd_id)
+{
+ struct ca_pmt_descriptor *pmt_descriptors = NULL;
+ uint32_t pmt_descriptors_length = 0;
+ struct ca_pmt_stream *pmt_streams = NULL;
+ uint32_t total_required_length = 0;
+ struct ca_pmt_descriptor *cur_d;
+ struct ca_pmt_stream *cur_s;
+ int result = -1;
+
+ // extract the descriptors and streams
+ if (en50221_ca_extract_pmt_descriptors(pmt, &pmt_descriptors))
+ goto cleanup;
+ if (en50221_ca_extract_streams(pmt, &pmt_streams))
+ goto cleanup;
+
+ // try and merge them if we have no PMT descriptors
+ if ((pmt_descriptors == NULL) && move_ca_descriptors) {
+ en50221_ca_try_move_pmt_descriptors(&pmt_descriptors,
+ &pmt_streams);
+ }
+ // calculate the length of all descriptors/streams and the total length required
+ total_required_length =
+ en50221_ca_calculate_length(pmt_descriptors,
+ &pmt_descriptors_length,
+ pmt_streams);
+
+ // ensure we were supplied with enough data
+ if (total_required_length > data_length) {
+ goto cleanup;
+ }
+ // format the start of the PMT
+ uint32_t data_pos = 0;
+ data[data_pos++] = ca_pmt_list_management;
+ data[data_pos++] = mpeg_pmt_section_program_number(pmt) >> 8;
+ data[data_pos++] = mpeg_pmt_section_program_number(pmt);
+ data[data_pos++] =
+ (pmt->head.version_number << 1) | pmt->head.
+ current_next_indicator;
+ data[data_pos++] = (pmt_descriptors_length >> 8) & 0x0f;
+ data[data_pos++] = pmt_descriptors_length;
+
+ // append the PMT descriptors
+ if (pmt_descriptors_length) {
+ data[data_pos++] = ca_pmt_cmd_id;
+ cur_d = pmt_descriptors;
+ while (cur_d) {
+ memcpy(data + data_pos, cur_d->descriptor,
+ cur_d->length);
+ data_pos += cur_d->length;
+ cur_d = cur_d->next;
+ }
+ }
+ // now, append the streams
+ cur_s = pmt_streams;
+ while (cur_s) {
+ data[data_pos++] = cur_s->stream_type;
+ data[data_pos++] = (cur_s->pid >> 8) & 0x1f;
+ data[data_pos++] = cur_s->pid;
+ data[data_pos++] = (cur_s->descriptors_length >> 8) & 0x0f;
+ data[data_pos++] = cur_s->descriptors_length;
+
+ // append the stream descriptors
+ if (cur_s->descriptors_length) {
+ data[data_pos++] = ca_pmt_cmd_id;
+ cur_d = cur_s->descriptors;
+ while (cur_d) {
+ memcpy(data + data_pos, cur_d->descriptor,
+ cur_d->length);
+ data_pos += cur_d->length;
+ cur_d = cur_d->next;
+ }
+ }
+ cur_s = cur_s->next;
+ }
+ result = data_pos;
+
+
+ cleanup:
+ // free the PMT descriptors
+ cur_d = pmt_descriptors;
+ while (cur_d) {
+ struct ca_pmt_descriptor *next = cur_d->next;
+ free(cur_d);
+ cur_d = next;
+ }
+
+ // free the streams
+ cur_s = pmt_streams;
+ while (cur_s) {
+ struct ca_pmt_stream *next_s = cur_s->next;
+
+ // free the stream descriptors
+ cur_d = cur_s->descriptors;
+ while (cur_d) {
+ struct ca_pmt_descriptor *next_d = cur_d->next;
+ free(cur_d);
+ cur_d = next_d;
+ }
+
+ free(cur_s);
+ cur_s = next_s;
+ }
+ return result;
+}
+
+
+
+
+
+
+
+static int en50221_ca_extract_pmt_descriptors(struct mpeg_pmt_section *pmt,
+ struct ca_pmt_descriptor **outdescriptors)
+{
+ struct ca_pmt_descriptor *descriptors = NULL;
+ struct ca_pmt_descriptor *descriptors_tail = NULL;
+ struct ca_pmt_descriptor *cur_d;
+
+ struct descriptor *cur_descriptor;
+ mpeg_pmt_section_descriptors_for_each(pmt, cur_descriptor) {
+ if (cur_descriptor->tag == dtag_mpeg_ca) {
+ // create a new structure for this one
+ struct ca_pmt_descriptor *new_d =
+ malloc(sizeof(struct ca_pmt_descriptor));
+ if (new_d == NULL) {
+ goto error_exit;
+ }
+ new_d->descriptor = (uint8_t *) cur_descriptor;
+ new_d->length = cur_descriptor->len + 2;
+ new_d->next = NULL;
+
+ // append it to the list
+ if (descriptors == NULL) {
+ descriptors = new_d;
+ } else {
+ descriptors_tail->next = new_d;
+ }
+ descriptors_tail = new_d;
+ }
+ }
+ *outdescriptors = descriptors;
+ return 0;
+
+error_exit:
+ cur_d = descriptors;
+ while (cur_d) {
+ struct ca_pmt_descriptor *next = cur_d->next;
+ free(cur_d);
+ cur_d = next;
+ }
+ return -1;
+}
+
+static int en50221_ca_extract_streams(struct mpeg_pmt_section *pmt,
+ struct ca_pmt_stream **outstreams)
+{
+ struct ca_pmt_stream *streams = NULL;
+ struct ca_pmt_stream *streams_tail = NULL;
+ struct mpeg_pmt_stream *cur_stream;
+ struct descriptor *cur_descriptor;
+ struct ca_pmt_stream *cur_s;
+
+ mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
+ struct ca_pmt_descriptor *descriptors_tail = NULL;
+
+ // create a new structure
+ struct ca_pmt_stream *new_s =
+ malloc(sizeof(struct ca_pmt_stream));
+ if (new_s == NULL) {
+ goto exit_cleanup;
+ }
+ new_s->stream_type = cur_stream->stream_type;
+ new_s->pid = cur_stream->pid;
+ new_s->descriptors = NULL;
+ new_s->next = NULL;
+ new_s->descriptors_count = 0;
+
+ // append it to the list
+ if (streams == NULL) {
+ streams = new_s;
+ } else {
+ streams_tail->next = new_s;
+ }
+ streams_tail = new_s;
+
+ // now process the descriptors
+ mpeg_pmt_stream_descriptors_for_each(cur_stream,
+ cur_descriptor) {
+ if (cur_descriptor->tag == dtag_mpeg_ca) {
+ // create a new structure
+ struct ca_pmt_descriptor *new_d =
+ malloc(sizeof(struct ca_pmt_descriptor));
+ if (new_d == NULL) {
+ goto exit_cleanup;
+ }
+ new_d->descriptor =
+ (uint8_t *) cur_descriptor;
+ new_d->length = cur_descriptor->len + 2;
+ new_d->next = NULL;
+
+ // append it to the list
+ if (new_s->descriptors == NULL) {
+ new_s->descriptors = new_d;
+ } else {
+ descriptors_tail->next = new_d;
+ }
+ descriptors_tail = new_d;
+ new_s->descriptors_count++;
+ }
+ }
+ }
+ *outstreams = streams;
+ return 0;
+
+exit_cleanup:
+ // free the streams
+ cur_s = streams;
+ while (cur_s) {
+ struct ca_pmt_stream *next_s = cur_s->next;
+
+ // free the stream descriptors
+ struct ca_pmt_descriptor *cur_d = cur_s->descriptors;
+ while (cur_d) {
+ struct ca_pmt_descriptor *next_d = cur_d->next;
+ free(cur_d);
+ cur_d = next_d;
+ }
+
+ free(cur_s);
+ cur_s = next_s;
+ }
+ return -1;
+}
+
+static void en50221_ca_try_move_pmt_descriptors(struct ca_pmt_descriptor **pmt_descriptors,
+ struct ca_pmt_stream **pmt_streams)
+{
+ // get the first stream
+ struct ca_pmt_stream *first_stream = *pmt_streams;
+ if (first_stream == NULL)
+ return;
+
+ // Check that all the other streams with CA descriptors have exactly the same CA descriptors
+ struct ca_pmt_stream *cur_stream = first_stream->next;
+ while (cur_stream) {
+ // if there are differing numbers of descriptors, exit right now
+ if (cur_stream->descriptors_count != first_stream->descriptors_count)
+ return;
+
+ // now verify the descriptors match
+ struct ca_pmt_descriptor *cur_descriptor = cur_stream->descriptors;
+ struct ca_pmt_descriptor *first_cur_descriptor = first_stream->descriptors;
+ while (cur_descriptor) {
+ // check the descriptors are the same length
+ if (cur_descriptor->length != first_cur_descriptor->length)
+ return;
+
+ // check their contents match
+ if (memcmp(cur_descriptor->descriptor,
+ first_cur_descriptor->descriptor,
+ cur_descriptor->length)) {
+ return;
+ }
+ // move to next
+ cur_descriptor = cur_descriptor->next;
+ first_cur_descriptor = first_cur_descriptor->next;
+ }
+
+ // move to next
+ cur_stream = cur_stream->next;
+ }
+
+ // if we end up here, all descriptors in all streams matched
+
+ // hook the first stream's descriptors into the PMT's
+ *pmt_descriptors = first_stream->descriptors;
+ first_stream->descriptors = NULL;
+ first_stream->descriptors_count = 0;
+
+ // now free up all the descriptors in the other streams
+ cur_stream = first_stream->next;
+ while (cur_stream) {
+ struct ca_pmt_descriptor *cur_descriptor = cur_stream->descriptors;
+ while (cur_descriptor) {
+ struct ca_pmt_descriptor *next = cur_descriptor->next;
+ free(cur_descriptor);
+ cur_descriptor = next;
+ }
+ cur_stream->descriptors = NULL;
+ cur_stream->descriptors_count = 0;
+ cur_stream = cur_stream->next;
+ }
+}
+
+static uint32_t en50221_ca_calculate_length(struct ca_pmt_descriptor *pmt_descriptors,
+ uint32_t *pmt_descriptors_length,
+ struct ca_pmt_stream *pmt_streams)
+{
+ uint32_t total_required_length = 6; // header
+ struct ca_pmt_stream *cur_s;
+
+ // calcuate the PMT descriptors length
+ (*pmt_descriptors_length) = 0;
+ struct ca_pmt_descriptor *cur_d = pmt_descriptors;
+ while (cur_d) {
+ (*pmt_descriptors_length) += cur_d->length;
+ cur_d = cur_d->next;
+ }
+
+ // add on 1 byte for the ca_pmt_cmd_id if we have some descriptors.
+ if (*pmt_descriptors_length)
+ (*pmt_descriptors_length)++;
+
+ // update the total required length
+ total_required_length += *pmt_descriptors_length;
+
+ // calculate the length of descriptors in the streams
+ cur_s = pmt_streams;
+ while (cur_s) {
+ // calculate the size of descriptors in this stream
+ cur_s->descriptors_length = 0;
+ cur_d = cur_s->descriptors;
+ while (cur_d) {
+ cur_s->descriptors_length += cur_d->length;
+ cur_d = cur_d->next;
+ }
+
+ // add on 1 byte for the ca_pmt_cmd_id if we have some descriptors.
+ if (cur_s->descriptors_length)
+ cur_s->descriptors_length++;
+
+ // update the total required length;
+ total_required_length += 5 + cur_s->descriptors_length;
+
+ cur_s = cur_s->next;
+ }
+
+ // done
+ return total_required_length;
+}
+
+static int en50221_app_ca_parse_info(struct en50221_app_ca *ca,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data, uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ data += length_field_len;
+
+ // parse
+ uint32_t ca_id_count = asn_data_length / 2;
+
+ // byteswap the IDs
+ uint16_t *ids = (uint16_t *) data;
+ uint32_t i;
+ for (i = 0; i < ca_id_count; i++) {
+ bswap16(data);
+ data += 2;
+ }
+
+ // tell the app
+ pthread_mutex_lock(&ca->lock);
+ en50221_app_ca_info_callback cb = ca->ca_info_callback;
+ void *cb_arg = ca->ca_info_callback_arg;
+ pthread_mutex_unlock(&ca->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, ca_id_count,
+ ids);
+ }
+ return 0;
+}
+
+static int en50221_app_ca_parse_reply(struct en50221_app_ca *ca,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data, uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length < 4) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ data += length_field_len;
+ data_length -= length_field_len;
+
+ // process the reply table to fix endian issues
+ uint32_t pos = 4;
+ bswap16(data);
+ while (pos < asn_data_length) {
+ bswap16(data + pos);
+ pos += 3;
+ }
+
+ // tell the app
+ pthread_mutex_lock(&ca->lock);
+ en50221_app_ca_pmt_reply_callback cb = ca->ca_pmt_reply_callback;
+ void *cb_arg = ca->ca_pmt_reply_callback_arg;
+ pthread_mutex_unlock(&ca->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ (struct en50221_app_pmt_reply *) data,
+ asn_data_length);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_ca.h b/lib/libdvben50221/en50221_app_ca.h
new file mode 100644
index 0000000..7405b06
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_ca.h
@@ -0,0 +1,264 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_ca_H__
+#define __EN50221_APPLICATION_ca_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+#include <libucsi/mpeg/pmt_section.h>
+#include <libucsi/dvb/descriptor.h>
+
+#define CA_LIST_MANAGEMENT_MORE 0x00
+#define CA_LIST_MANAGEMENT_FIRST 0x01
+#define CA_LIST_MANAGEMENT_LAST 0x02
+#define CA_LIST_MANAGEMENT_ONLY 0x03
+#define CA_LIST_MANAGEMENT_ADD 0x04
+#define CA_LIST_MANAGEMENT_UPDATE 0x05
+
+#define CA_PMT_CMD_ID_OK_DESCRAMBLING 0x01
+#define CA_PMT_CMD_ID_OK_MMI 0x02
+#define CA_PMT_CMD_ID_QUERY 0x03
+#define CA_PMT_CMD_ID_NOT_SELECTED 0x04
+
+#define CA_ENABLE_DESCRAMBLING_POSSIBLE 0x01
+#define CA_ENABLE_DESCRAMBLING_POSSIBLE_PURCHASE 0x02
+#define CA_ENABLE_DESCRAMBLING_POSSIBLE_TECHNICAL 0x03
+#define CA_ENABLE_DESCRAMBLING_NOT_POSSIBLE_NO_ENTITLEMENT 0x71
+#define CA_ENABLE_DESCRAMBLING_NOT_POSSIBLE_TECHNICAL 0x73
+
+
+#define EN50221_APP_CA_RESOURCEID MKRID(3,1,1)
+
+/**
+ * PMT reply structure.
+ */
+struct en50221_app_pmt_reply {
+ uint16_t program_number;
+ EBIT3(uint8_t reserved_1 : 2;,
+ uint8_t version_number : 5;,
+ uint8_t current_next_indicator : 1;);
+ EBIT2(uint8_t CA_enable_flag : 1;,
+ uint8_t CA_enable : 7;);
+ /* struct en50221_app_pmt_stream streams[] */
+} __attribute__ ((packed));
+
+/**
+ * A stream within a pmt reply structure.
+ */
+struct en50221_app_pmt_stream {
+ EBIT2(uint16_t reserved_1 : 3;,
+ uint16_t es_pid :13;);
+ EBIT2(uint8_t CA_enable_flag : 1;,
+ uint8_t CA_enable : 7;);
+} __attribute__ ((packed));
+
+/**
+ * Convenience iterator for the streams field of the en50221_app_pmt_reply structure.
+ *
+ * @param pmt Pointer to the en50221_app_pmt_reply structure.
+ * @param pos Variable holding a pointer to the current en50221_app_pmt_stream.
+ * @param size Total size of the PMT reply.
+ */
+#define en50221_app_pmt_reply_streams_for_each(pmt, pos, size) \
+ for ((pos) = en50221_app_pmt_reply_streams_first(pmt, size); \
+ (pos); \
+ (pos) = en50221_app_pmt_reply_streams_next(pmt, pos, size))
+
+
+/**
+ * Type definition for command - called when we receive a ca info response.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param ca_id_count Number of ca_system_ids.
+ * @param ca_ids Pointer to list of ca_system_ids.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_ca_info_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t ca_id_count,
+ uint16_t * ca_ids);
+
+/**
+ * Type definition for pmt_reply - called when we receive a pmt_reply.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param reply Pointer to a struct en50221_app_pmt_reply.
+ * @param reply_size Total size of the struct en50221_app_pmt_reply in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_ca_pmt_reply_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ struct en50221_app_pmt_reply *reply,
+ uint32_t reply_size);
+
+/**
+ * Opaque type representing a ca resource.
+ */
+struct en50221_app_ca;
+
+/**
+ * Create an instance of the ca resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_ca *en50221_app_ca_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the ca resource.
+ *
+ * @param ca Instance to destroy.
+ */
+extern void en50221_app_ca_destroy(struct en50221_app_ca *ca);
+
+/**
+ * Register the callback for when we receive a ca info.
+ *
+ * @param ca ca resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_ca_register_info_callback(struct en50221_app_ca *ca,
+ en50221_app_ca_info_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a pmt_reply.
+ *
+ * @param ca ca resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_ca_register_pmt_reply_callback(struct en50221_app_ca *ca,
+ en50221_app_ca_pmt_reply_callback callback,
+ void *arg);
+
+/**
+ * Send a ca_info_req to the CAM.
+ *
+ * @param ca ca resource instance.
+ * @param session_number Session number to send it on.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_ca_info_enq(struct en50221_app_ca *ca,
+ uint16_t session_number);
+
+/**
+ * Send a ca_pmt structure to the CAM.
+ *
+ * @param ca ca resource instance.
+ * @param session_number Session number to send it on.
+ * @param ca_pmt A ca_pmt structure formatted with the en50221_ca_format_pmt() function.
+ * @param ca_pmt_length Length of ca_pmt structure in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_ca_pmt(struct en50221_app_ca *ca,
+ uint16_t session_number,
+ uint8_t * ca_pmt,
+ uint32_t ca_pmt_length);
+
+/**
+ * Transform a libucsi PMT into a binary structure for sending to a CAM.
+ *
+ * @param pmt The source PMT structure.
+ * @param data Pointer to data buffer to write it to.
+ * @param data_length Number of bytes available in data buffer.
+ * @param move_ca_descriptors If non-zero, will attempt to move CA descriptors
+ * in order to reduce the size of the formatted CAPMT.
+ * @param ca_pmt_list_management One of the CA_LIST_MANAGEMENT_*.
+ * @param ca_pmt_cmd_id One of the CA_PMT_CMD_ID_*.
+ * @return Number of bytes used, or -1 on error.
+ */
+extern int en50221_ca_format_pmt(struct mpeg_pmt_section *pmt,
+ uint8_t * data,
+ uint32_t data_length,
+ int move_ca_descriptors,
+ uint8_t ca_pmt_list_management,
+ uint8_t ca_pmt_cmd_id);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param ca CA instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_ca_message(struct en50221_app_ca *ca,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+
+
+
+static inline struct en50221_app_pmt_stream *
+ en50221_app_pmt_reply_streams_first(struct en50221_app_pmt_reply *reply,
+ uint32_t reply_size)
+{
+ uint32_t pos = sizeof(struct en50221_app_pmt_reply);
+
+ if (pos >= reply_size)
+ return NULL;
+
+ return (struct en50221_app_pmt_stream *) ((uint8_t *) reply + pos);
+}
+
+static inline struct en50221_app_pmt_stream *
+ en50221_app_pmt_reply_streams_next(struct en50221_app_pmt_reply *reply,
+ struct en50221_app_pmt_stream *pos,
+ uint32_t reply_size)
+{
+ uint8_t *end = (uint8_t *) reply + reply_size;
+ uint8_t *next =
+ (uint8_t *) pos +
+ sizeof(struct en50221_app_pmt_stream);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct en50221_app_pmt_stream *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libdvben50221/en50221_app_datetime.c b/lib/libdvben50221/en50221_app_datetime.c
new file mode 100644
index 0000000..6777003
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_datetime.c
@@ -0,0 +1,173 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include <libucsi/dvb/types.h>
+#include "en50221_app_datetime.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_datetime {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_datetime_enquiry_callback callback;
+ void *callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_datetime_parse_enquiry(struct en50221_app_datetime *datetime,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+
+struct en50221_app_datetime *en50221_app_datetime_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_datetime *datetime = NULL;
+
+ // create structure and set it up
+ datetime = malloc(sizeof(struct en50221_app_datetime));
+ if (datetime == NULL) {
+ return NULL;
+ }
+ datetime->funcs = funcs;
+ datetime->callback = NULL;
+
+ pthread_mutex_init(&datetime->lock, NULL);
+
+ // done
+ return datetime;
+}
+
+void en50221_app_datetime_destroy(struct en50221_app_datetime *datetime)
+{
+ pthread_mutex_destroy(&datetime->lock);
+ free(datetime);
+}
+
+void en50221_app_datetime_register_enquiry_callback(struct en50221_app_datetime *datetime,
+ en50221_app_datetime_enquiry_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&datetime->lock);
+ datetime->callback = callback;
+ datetime->callback_arg = arg;
+ pthread_mutex_unlock(&datetime->lock);
+}
+
+int en50221_app_datetime_send(struct en50221_app_datetime *datetime,
+ uint16_t session_number,
+ time_t utc_time, int time_offset)
+{
+ uint8_t data[11];
+ int data_length;
+
+ data[0] = (TAG_DATE_TIME >> 16) & 0xFF;
+ data[1] = (TAG_DATE_TIME >> 8) & 0xFF;
+ data[2] = TAG_DATE_TIME & 0xFF;
+ if (time_offset != -1) {
+ data[3] = 7;
+ unixtime_to_dvbdate(utc_time, data + 4);
+ data[9] = time_offset >> 8;
+ data[10] = time_offset;
+ data_length = 11;
+ } else {
+ data[3] = 5;
+ unixtime_to_dvbdate(utc_time, data + 4);
+ data_length = 9;
+ }
+ return datetime->funcs->send_data(datetime->funcs->arg,
+ session_number, data,
+ data_length);
+}
+
+int en50221_app_datetime_message(struct en50221_app_datetime *datetime,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_DATE_TIME_ENQUIRY:
+ return en50221_app_datetime_parse_enquiry(datetime,
+ slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+
+
+
+
+
+
+
+static int en50221_app_datetime_parse_enquiry(struct en50221_app_datetime *datetime,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t response_interval = data[1];
+
+ // tell the app
+ pthread_mutex_lock(&datetime->lock);
+ en50221_app_datetime_enquiry_callback cb = datetime->callback;
+ void *cb_arg = datetime->callback_arg;
+ pthread_mutex_unlock(&datetime->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ response_interval);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_datetime.h b/lib/libdvben50221/en50221_app_datetime.h
new file mode 100644
index 0000000..4660630
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_datetime.h
@@ -0,0 +1,119 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_DATETIME_H__
+#define __EN50221_APPLICATION_DATETIME_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_DATETIME_RESOURCEID MKRID(36,1,1)
+
+/**
+ * Type definition for enquiry - called when we receive a date/time enquiry from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param response_interval Response interval requested by CAM.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_datetime_enquiry_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t response_interval);
+
+/**
+ * Opaque type representing a datetime resource.
+ */
+struct en50221_app_datetime;
+
+/**
+ * Create an instance of the datetime resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_datetime
+ *en50221_app_datetime_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the datetime resource.
+ *
+ * @param datetime Instance to destroy.
+ */
+extern void en50221_app_datetime_destroy(struct en50221_app_datetime *datetime);
+
+/**
+ * Register the callback for when we receive a enquiry request.
+ *
+ * @param datetime datetime resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_datetime_register_enquiry_callback(struct en50221_app_datetime *datetime,
+ en50221_app_datetime_enquiry_callback callback,
+ void *arg);
+
+/**
+ * Send the time to the CAM.
+ *
+ * @param datetime datetime resource instance.
+ * @param session_number Session number to send it on.
+ * @param utc_time UTC time in unix time format.
+ * @param time_offset If -1, the field will not be transmitted, otherwise it is the offset between
+ * UTC and local time in minutes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_datetime_send(struct en50221_app_datetime *datetime,
+ uint16_t session_number,
+ time_t utc_time,
+ int time_offset);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param datetime datetime instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_datetime_message(struct en50221_app_datetime *datetime,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_dvb.c b/lib/libdvben50221/en50221_app_dvb.c
new file mode 100644
index 0000000..21b2bec
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_dvb.c
@@ -0,0 +1,282 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include "en50221_app_dvb.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_dvb {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_dvb_tune_callback tune_callback;
+ void *tune_callback_arg;
+
+ en50221_app_dvb_replace_callback replace_callback;
+ void *replace_callback_arg;
+
+ en50221_app_dvb_clear_replace_callback clear_replace_callback;
+ void *clear_replace_callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_dvb_parse_tune(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+static int en50221_app_dvb_parse_replace(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+
+struct en50221_app_dvb *en50221_app_dvb_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_dvb *dvb = NULL;
+
+ // create structure and set it up
+ dvb = malloc(sizeof(struct en50221_app_dvb));
+ if (dvb == NULL) {
+ return NULL;
+ }
+ dvb->funcs = funcs;
+ dvb->tune_callback = NULL;
+ dvb->replace_callback = NULL;
+ dvb->clear_replace_callback = NULL;
+
+ pthread_mutex_init(&dvb->lock, NULL);
+
+ // done
+ return dvb;
+}
+
+void en50221_app_dvb_destroy(struct en50221_app_dvb *dvb)
+{
+ pthread_mutex_destroy(&dvb->lock);
+ free(dvb);
+}
+
+void en50221_app_dvb_register_tune_callback(struct en50221_app_dvb *dvb,
+ en50221_app_dvb_tune_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&dvb->lock);
+ dvb->tune_callback = callback;
+ dvb->tune_callback_arg = arg;
+ pthread_mutex_unlock(&dvb->lock);
+}
+
+void en50221_app_dvb_register_replace_callback(struct en50221_app_dvb *dvb,
+ en50221_app_dvb_replace_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&dvb->lock);
+ dvb->replace_callback = callback;
+ dvb->replace_callback_arg = arg;
+ pthread_mutex_unlock(&dvb->lock);
+}
+
+void en50221_app_dvb_register_clear_replace_callback(struct en50221_app_dvb *dvb,
+ en50221_app_dvb_clear_replace_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&dvb->lock);
+ dvb->clear_replace_callback = callback;
+ dvb->clear_replace_callback_arg = arg;
+ pthread_mutex_unlock(&dvb->lock);
+}
+
+int en50221_app_dvb_ask_release(struct en50221_app_dvb *dvb,
+ uint16_t session_number)
+{
+ uint8_t data[4];
+
+ data[0] = (TAG_ASK_RELEASE >> 16) & 0xFF;
+ data[1] = (TAG_ASK_RELEASE >> 8) & 0xFF;
+ data[2] = TAG_ASK_RELEASE & 0xFF;
+ data[3] = 0;
+
+ return dvb->funcs->send_data(dvb->funcs->arg, session_number, data, 4);
+}
+
+int en50221_app_dvb_message(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_TUNE:
+ return en50221_app_dvb_parse_tune(dvb, slot_id,
+ session_number, data + 3,
+ data_length - 3);
+ case TAG_REPLACE:
+ return en50221_app_dvb_parse_replace(dvb, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_CLEAR_REPLACE:
+ return en50221_app_dvb_parse_clear_replace(dvb, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+
+
+
+
+
+
+
+static int en50221_app_dvb_parse_tune(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data, uint32_t data_length)
+{
+ // validate data
+ if (data_length < 9) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 8) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t *tune_data = data + 1;
+
+ // parse it
+ uint16_t network_id = (tune_data[0] << 8) | tune_data[1];
+ uint16_t original_network_id = (tune_data[2] << 8) | tune_data[3];
+ uint16_t transport_stream_id = (tune_data[4] << 8) | tune_data[5];
+ uint16_t service_id = (tune_data[6] << 8) | tune_data[7];
+
+ // tell the app
+ pthread_mutex_lock(&dvb->lock);
+ en50221_app_dvb_tune_callback cb = dvb->tune_callback;
+ void *cb_arg = dvb->tune_callback_arg;
+ pthread_mutex_unlock(&dvb->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, network_id,
+ original_network_id, transport_stream_id,
+ service_id);
+ }
+ return 0;
+}
+
+static int en50221_app_dvb_parse_replace(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length < 6) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 5) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t *replace_data = data + 1;
+
+ // parse it
+ uint8_t replacement_ref = replace_data[0];
+ uint16_t replace_pid =
+ ((replace_data[1] & 0x1f) << 8) | replace_data[2];
+ uint16_t replacement_pid =
+ ((replace_data[3] & 0x1f) << 8) | replace_data[4];
+
+ // tell the app
+ pthread_mutex_lock(&dvb->lock);
+ en50221_app_dvb_replace_callback cb = dvb->replace_callback;
+ void *cb_arg = dvb->replace_callback_arg;
+ pthread_mutex_unlock(&dvb->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, replacement_ref,
+ replace_pid, replacement_pid);
+ }
+ return 0;
+}
+
+static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length < 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t *replace_data = data + 1;
+
+ // parse it
+ uint8_t replacement_ref = replace_data[0];
+
+ // tell the app
+ pthread_mutex_lock(&dvb->lock);
+ en50221_app_dvb_clear_replace_callback cb =
+ dvb->clear_replace_callback;
+ void *cb_arg = dvb->clear_replace_callback_arg;
+ pthread_mutex_unlock(&dvb->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ replacement_ref);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_dvb.h b/lib/libdvben50221/en50221_app_dvb.h
new file mode 100644
index 0000000..be74e6b
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_dvb.h
@@ -0,0 +1,176 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_DVB_H__
+#define __EN50221_APPLICATION_DVB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_DVB_RESOURCEID MKRID(32,1,1)
+
+
+/**
+ * Type definition for tune - called when we receive a tune request from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param network_id Network id requested by CAM.
+ * @param original_network_id Original Network id requested by CAM.
+ * @param transport_stream_id Transport stream id requested by CAM.
+ * @param service_id Service id requested by CAM.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_dvb_tune_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint16_t network_id,
+ uint32_t original_network_id,
+ uint16_t transport_stream_id,
+ uint16_t service_id);
+
+/**
+ * Type definition for replace - called when we receive a replace request from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param replacement_ref Replacement ref.
+ * @param replaced_pid PID to replace.
+ * @param replacement_pid PID to replace it with.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_dvb_replace_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t replacement_ref,
+ uint16_t replaced_pid,
+ uint16_t replacement_pid);
+
+
+/**
+ * Type definition for clear_replace - called when we receive a clear_replace request from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param replacement_ref Replacement ref.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_dvb_clear_replace_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t replacement_ref);
+
+
+/**
+ * Opaque type representing a dvb resource.
+ */
+struct en50221_app_dvb;
+
+/**
+ * Create an instance of the dvb resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_dvb *en50221_app_dvb_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the dvb resource.
+ *
+ * @param dvb Instance to destroy.
+ */
+extern void en50221_app_dvb_destroy(struct en50221_app_dvb *dvb);
+
+/**
+ * Register the callback for when we receive a tune request.
+ *
+ * @param dvb DVB resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_dvb_register_tune_callback(struct en50221_app_dvb *dvb,
+ en50221_app_dvb_tune_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a replace request.
+ *
+ * @param dvb DVB resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_dvb_register_replace_callback(struct en50221_app_dvb *dvb,
+ en50221_app_dvb_replace_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a clear replace request.
+ *
+ * @param dvb DVB resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_dvb_register_clear_replace_callback(struct en50221_app_dvb *dvb,
+ en50221_app_dvb_clear_replace_callback callback,
+ void *arg);
+
+/**
+ * Send an ask release request to the CAM.
+ *
+ * @param dvb DVB resource instance.
+ * @param session_number Session number to send it on.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_dvb_ask_release(struct en50221_app_dvb *dvb,
+ uint16_t session_number);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param dvb dvb instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_dvb_message(struct en50221_app_dvb *dvb,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_epg.c b/lib/libdvben50221/en50221_app_epg.c
new file mode 100644
index 0000000..87b4743
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_epg.c
@@ -0,0 +1,167 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include <libucsi/dvb/types.h>
+#include "en50221_app_epg.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_epg {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_epg_reply_callback callback;
+ void *callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_epg_parse_reply(struct en50221_app_epg *private,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+
+struct en50221_app_epg *en50221_app_epg_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_epg *epg = NULL;
+
+ // create structure and set it up
+ epg = malloc(sizeof(struct en50221_app_epg));
+ if (epg == NULL) {
+ return NULL;
+ }
+ epg->funcs = funcs;
+ epg->callback = NULL;
+
+ pthread_mutex_init(&epg->lock, NULL);
+
+ // done
+ return epg;
+}
+
+void en50221_app_epg_destroy(struct en50221_app_epg *epg)
+{
+ pthread_mutex_destroy(&epg->lock);
+ free(epg);
+}
+
+void en50221_app_epg_register_enquiry_callback(struct en50221_app_epg *epg,
+ en50221_app_epg_reply_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&epg->lock);
+ epg->callback = callback;
+ epg->callback_arg = arg;
+ pthread_mutex_unlock(&epg->lock);
+}
+
+int en50221_app_epg_enquire(struct en50221_app_epg *epg,
+ uint16_t session_number,
+ uint8_t command_id,
+ uint16_t network_id,
+ uint16_t original_network_id,
+ uint16_t transport_stream_id,
+ uint16_t service_id, uint16_t event_id)
+{
+ uint8_t data[15];
+
+ data[0] = (TAG_EPG_ENQUIRY >> 16) & 0xFF;
+ data[1] = (TAG_EPG_ENQUIRY >> 8) & 0xFF;
+ data[2] = TAG_EPG_ENQUIRY & 0xFF;
+ data[3] = 11;
+ data[4] = command_id;
+ data[5] = network_id >> 8;
+ data[6] = network_id;
+ data[7] = original_network_id >> 8;
+ data[8] = original_network_id;
+ data[9] = transport_stream_id >> 8;
+ data[10] = transport_stream_id;
+ data[11] = service_id >> 8;
+ data[12] = service_id;
+ data[13] = event_id >> 8;
+ data[14] = event_id;
+ return epg->funcs->send_data(epg->funcs->arg, session_number, data, 15);
+}
+
+int en50221_app_epg_message(struct en50221_app_epg *epg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ struct en50221_app_epg *private = (struct en50221_app_epg *) epg;
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_EPG_REPLY:
+ return en50221_app_epg_parse_reply(private, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+static int en50221_app_epg_parse_reply(struct en50221_app_epg *epg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t event_status = data[1];
+
+ // tell the app
+ pthread_mutex_lock(&epg->lock);
+ en50221_app_epg_reply_callback cb = epg->callback;
+ void *cb_arg = epg->callback_arg;
+ pthread_mutex_unlock(&epg->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, event_status);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_epg.h b/lib/libdvben50221/en50221_app_epg.h
new file mode 100644
index 0000000..dcfe9da
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_epg.h
@@ -0,0 +1,138 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_epg_H__
+#define __EN50221_APPLICATION_epg_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EPG_COMMAND_ID_MMI 0x02
+#define EPG_COMMAND_ID_QUERY 0x03
+
+#define EPG_EVENTSTATUS_ENTITLEMENT_UNKNOWN 0x00
+#define EPG_EVENTSTATUS_ENTITLEMENT_AVAILABLE 0x01
+#define EPG_EVENTSTATUS_ENTITLEMENT_NOT_AVAILABLE 0x02
+#define EPG_EVENTSTATUS_MMI_DIALOGUE_REQUIRED 0x03
+#define EPG_EVENTSTATUS_MMI_COMPLETE_UNKNOWN 0x04
+#define EPG_EVENTSTATUS_MMI_COMPLETE_AVAILABLE 0x05
+#define EPG_EVENTSTATUS_MMI_COMPLETE_NOT_AVAILABLE 0x06
+
+#define EN50221_APP_EPG_RESOURCEID(INSTANCE_NUM) MKRID(120,(INSTANCE_NUM),1)
+
+
+
+/**
+ * Type definition for reply - called when we receive an EPG reply from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param event_status One of the EPG_EVENTSTATUS_* values.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_epg_reply_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t event_status);
+
+/**
+ * Opaque type representing a epg resource.
+ */
+struct en50221_app_epg;
+
+/**
+ * Create an instance of the epg resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_epg *en50221_app_epg_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the epg resource.
+ *
+ * @param epg Instance to destroy.
+ */
+extern void en50221_app_epg_destroy(struct en50221_app_epg *epg);
+
+/**
+ * Register the callback for when we receive a enquiry response.
+ *
+ * @param epg epg resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_epg_register_reply_callback(struct en50221_app_epg *epg,
+ en50221_app_epg_reply_callback callback,
+ void *arg);
+
+/**
+ * Enquire about the entitlement status for an EPG entry.
+ *
+ * @param epg epg resource instance.
+ * @param session_number Session number to send it on.
+ * @param command_id One of the EPG_COMMAND_ID_* fields.
+ * @param network_id Network ID concerned.
+ * @param original_network_id Original network ID concerned.
+ * @param transport_stream_id Transport stream ID concerned.
+ * @param service_id Service ID concerned.
+ * @param event_id Event ID concerned.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_epg_enquire(struct en50221_app_epg *epg,
+ uint16_t session_number,
+ uint8_t command_id,
+ uint16_t network_id,
+ uint16_t original_network_id,
+ uint16_t transport_stream_id,
+ uint16_t service_id,
+ uint16_t event_id);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param epg epg instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_epg_message(struct en50221_app_epg *epg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_lowspeed.c b/lib/libdvben50221/en50221_app_lowspeed.c
new file mode 100644
index 0000000..a66598a
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_lowspeed.c
@@ -0,0 +1,533 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include "en50221_app_lowspeed.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_lowspeed_session {
+ uint16_t session_number;
+ uint8_t *block_chain;
+ uint32_t block_length;
+
+ struct en50221_app_lowspeed_session *next;
+};
+
+struct en50221_app_lowspeed {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_lowspeed_command_callback command_callback;
+ void *command_callback_arg;
+
+ en50221_app_lowspeed_send_callback send_callback;
+ void *send_callback_arg;
+
+ struct en50221_app_lowspeed_session *sessions;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_lowspeed_parse_connect_on_channel(struct en50221_app_lowspeed_command *command,
+ uint8_t *data,
+ int data_length);
+static int en50221_app_lowspeed_parse_command(struct en50221_app_lowspeed *lowspeed,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *data,
+ uint32_t data_length);
+static int en50221_app_lowspeed_parse_send(struct en50221_app_lowspeed *lowspeed,
+ uint8_t slot_id,
+ uint16_t session_number,
+ int more_last,
+ uint8_t *data,
+ uint32_t data_length);
+
+
+
+struct en50221_app_lowspeed *en50221_app_lowspeed_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_lowspeed *lowspeed = NULL;
+
+ // create structure and set it up
+ lowspeed = malloc(sizeof(struct en50221_app_lowspeed));
+ if (lowspeed == NULL) {
+ return NULL;
+ }
+ lowspeed->funcs = funcs;
+ lowspeed->command_callback = NULL;
+ lowspeed->send_callback = NULL;
+ lowspeed->sessions = NULL;
+
+ pthread_mutex_init(&lowspeed->lock, NULL);
+
+ // done
+ return lowspeed;
+}
+
+void en50221_app_lowspeed_destroy(struct en50221_app_lowspeed *lowspeed)
+{
+ struct en50221_app_lowspeed_session *cur_s = lowspeed->sessions;
+ while (cur_s) {
+ struct en50221_app_lowspeed_session *next = cur_s->next;
+ if (cur_s->block_chain)
+ free(cur_s->block_chain);
+ free(cur_s);
+ cur_s = next;
+ }
+
+ pthread_mutex_destroy(&lowspeed->lock);
+ free(lowspeed);
+}
+
+void en50221_app_lowspeed_clear_session(struct en50221_app_lowspeed *lowspeed,
+ uint16_t session_number)
+{
+ pthread_mutex_lock(&lowspeed->lock);
+ struct en50221_app_lowspeed_session *cur_s = lowspeed->sessions;
+ struct en50221_app_lowspeed_session *prev_s = NULL;
+ while (cur_s) {
+ if (cur_s->session_number == session_number) {
+ if (cur_s->block_chain)
+ free(cur_s->block_chain);
+ if (prev_s) {
+ prev_s->next = cur_s->next;
+ } else {
+ lowspeed->sessions = cur_s->next;
+ }
+ free(cur_s);
+ return;
+ }
+
+ prev_s = cur_s;
+ cur_s = cur_s->next;
+ }
+ pthread_mutex_unlock(&lowspeed->lock);
+}
+
+void en50221_app_lowspeed_register_command_callback(struct en50221_app_lowspeed *lowspeed,
+ en50221_app_lowspeed_command_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&lowspeed->lock);
+ lowspeed->command_callback = callback;
+ lowspeed->command_callback_arg = arg;
+ pthread_mutex_unlock(&lowspeed->lock);
+}
+
+void en50221_app_lowspeed_register_send_callback(struct en50221_app_lowspeed *lowspeed,
+ en50221_app_lowspeed_send_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&lowspeed->lock);
+ lowspeed->send_callback = callback;
+ lowspeed->send_callback_arg = arg;
+ pthread_mutex_unlock(&lowspeed->lock);
+}
+
+int en50221_app_lowspeed_send_comms_reply(struct en50221_app_lowspeed *lowspeed,
+ uint16_t session_number,
+ uint8_t comms_reply_id,
+ uint8_t return_value)
+{
+ uint8_t data[6];
+
+ data[0] = (TAG_COMMS_REPLY >> 16) & 0xFF;
+ data[1] = (TAG_COMMS_REPLY >> 8) & 0xFF;
+ data[2] = TAG_COMMS_REPLY & 0xFF;
+ data[3] = 2;
+ data[4] = comms_reply_id;
+ data[5] = return_value;
+ return lowspeed->funcs->send_data(lowspeed->funcs->arg,
+ session_number, data, 6);
+}
+
+int en50221_app_lowspeed_send_comms_data(struct en50221_app_lowspeed *lowspeed,
+ uint16_t session_number,
+ uint8_t phase_id,
+ uint32_t tx_data_length,
+ uint8_t * tx_data)
+{
+ uint8_t buf[10];
+
+ // the spec defines this limit
+ if (tx_data_length > 254) {
+ return -1;
+ }
+ // set up the tag
+ buf[0] = (TAG_COMMS_RECV_LAST >> 16) & 0xFF;
+ buf[1] = (TAG_COMMS_RECV_LAST >> 8) & 0xFF;
+ buf[2] = TAG_COMMS_RECV_LAST & 0xFF;
+
+ // encode the length field
+ int length_field_len;
+ if ((length_field_len = asn_1_encode(tx_data_length + 1, buf + 3, 3)) < 0) {
+ return -1;
+ }
+ // the phase_id
+ buf[3 + length_field_len] = phase_id;
+
+ // build the iovecs
+ struct iovec iov[2];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 3 + length_field_len + 1;
+ iov[1].iov_base = tx_data;
+ iov[1].iov_len = tx_data_length;
+
+ // create the data and send it
+ return lowspeed->funcs->send_datav(lowspeed->funcs->arg,
+ session_number, iov, 2);
+}
+
+int en50221_app_lowspeed_message(struct en50221_app_lowspeed *lowspeed,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_COMMS_COMMAND:
+ return en50221_app_lowspeed_parse_command(lowspeed,
+ slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_COMMS_SEND_LAST:
+ return en50221_app_lowspeed_parse_send(lowspeed, slot_id,
+ session_number, 1,
+ data + 3,
+ data_length - 3);
+ case TAG_COMMS_SEND_MORE:
+ return en50221_app_lowspeed_parse_send(lowspeed, slot_id,
+ session_number, 0,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+static int en50221_app_lowspeed_parse_connect_on_channel(struct en50221_app_lowspeed_command *command,
+ uint8_t *data,
+ int data_length)
+{
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // check the tag
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+ if (tag != TAG_CONNECTION_DESCRIPTOR) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received bad CONNECT_ON_CHANNEL\n");
+ return -1;
+ }
+ data += 3;
+ data_length -= 3;
+
+ // parse the descriptor-length-field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ data += length_field_len;
+ data_length -= length_field_len;
+
+ // check length field
+ if (asn_data_length > data_length) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length < 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // get the descriptor type
+ command->u.connect_on_channel.descriptor_type = data[0];
+ data++;
+ data_length--;
+ asn_data_length--;
+
+ // deal with the descriptor itself
+ switch (command->u.connect_on_channel.descriptor_type) {
+ case CONNECTION_DESCRIPTOR_TYPE_TELEPHONE:
+ {
+ // get the raw descriptor and validate length
+ struct descriptor *d = (struct descriptor *) data;
+ if (asn_data_length < 2) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length != (2 + d->len)) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ if (d->tag != dtag_dvb_telephone) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received invalid telephone descriptor\n");
+ return -1;
+ }
+ // parse the telephone descriptor
+ command->u.connect_on_channel.descriptor.telephone = dvb_telephone_descriptor_codec(d);
+ if (command->u.connect_on_channel.descriptor.telephone == NULL) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received invalid telephone descriptor\n");
+ return -1;
+ }
+ data += 2 + d->len;
+ data_length -= 2 + d->len;
+ break;
+ }
+
+ case CONNECTION_DESCRIPTOR_TYPE_CABLE:
+ if (asn_data_length != 1) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ command->u.connect_on_channel.descriptor.cable_channel_id = data[0];
+ data++;
+ data_length--;
+ break;
+ default:
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unknown connection descriptor %02x\n",
+ command->u.connect_on_channel.descriptor_type);
+ return -1;
+ }
+
+ // parse the last bit
+ if (data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ command->u.connect_on_channel.retry_count = data[0];
+ command->u.connect_on_channel.timeout = data[1];
+
+ // ok
+ return 0;
+}
+
+static int en50221_app_lowspeed_parse_command(struct en50221_app_lowspeed *lowspeed,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length < 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ data += length_field_len;
+
+ // get command id
+ uint8_t command_id = data[0];
+ data++;
+ asn_data_length--;
+
+ // parse the command
+ struct en50221_app_lowspeed_command command;
+ switch (command_id) {
+ case COMMS_COMMAND_ID_CONNECT_ON_CHANNEL:
+ if (en50221_app_lowspeed_parse_connect_on_channel
+ (&command, data, asn_data_length)) {
+ return -1;
+ }
+ break;
+ case COMMS_COMMAND_ID_SET_PARAMS:
+ if (asn_data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ command.u.set_params.buffer_size = data[0];
+ command.u.set_params.timeout = data[1];
+ break;
+ case COMMS_COMMAND_ID_GET_NEXT_BUFFER:
+ if (asn_data_length != 1) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ command.u.get_next_buffer.phase_id = data[0];
+ break;
+
+ case COMMS_COMMAND_ID_DISCONNECT_ON_CHANNEL:
+ case COMMS_COMMAND_ID_ENQUIRE_STATUS:
+ break;
+
+ default:
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected command_id %02x\n", command_id);
+ return -1;
+ }
+
+ // tell the app
+ pthread_mutex_lock(&lowspeed->lock);
+ en50221_app_lowspeed_command_callback cb = lowspeed->command_callback;
+ void *cb_arg = lowspeed->command_callback_arg;
+ pthread_mutex_unlock(&lowspeed->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, command_id,
+ &command);
+ }
+ return 0;
+}
+
+static int en50221_app_lowspeed_parse_send(struct en50221_app_lowspeed *lowspeed,
+ uint8_t slot_id,
+ uint16_t session_number,
+ int more_last,
+ uint8_t *data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // skip over the length field
+ data += length_field_len;
+
+ // find previous session
+ pthread_mutex_lock(&lowspeed->lock);
+ struct en50221_app_lowspeed_session *cur_s = lowspeed->sessions;
+ while (cur_s) {
+ if (cur_s->session_number == session_number)
+ break;
+ cur_s = cur_s->next;
+ }
+
+ // more data is still to come
+ if (!more_last) {
+ // if there was no previous session, create one
+ if (cur_s == NULL) {
+ cur_s = malloc(sizeof(struct en50221_app_lowspeed_session));
+ if (cur_s == NULL) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Ran out of memory\n");
+ pthread_mutex_unlock(&lowspeed->lock);
+ return -1;
+ }
+ cur_s->session_number = session_number;
+ cur_s->block_chain = NULL;
+ cur_s->block_length = 0;
+ cur_s->next = lowspeed->sessions;
+ lowspeed->sessions = cur_s;
+ }
+ // append the data
+ uint8_t *new_data = realloc(cur_s->block_chain,
+ cur_s->block_length + asn_data_length);
+ if (new_data == NULL) {
+ print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
+ pthread_mutex_unlock(&lowspeed->lock);
+ return -1;
+ }
+ memcpy(new_data + cur_s->block_length, data, asn_data_length);
+ cur_s->block_chain = new_data;
+ cur_s->block_length += asn_data_length;
+
+ // done
+ pthread_mutex_unlock(&lowspeed->lock);
+ return 0;
+ }
+ // we hit the last of a possible chain of fragments
+ int do_free = 0;
+ if (cur_s != NULL) {
+ // we have a preceding fragment - need to append
+ uint8_t *new_data = realloc(cur_s->block_chain,
+ cur_s->block_length + asn_data_length);
+ if (new_data == NULL) {
+ print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
+ pthread_mutex_unlock(&lowspeed->lock);
+ return -1;
+ }
+ memcpy(new_data + cur_s->block_length, data, asn_data_length);
+ asn_data_length = cur_s->block_length + asn_data_length;
+ data = new_data;
+ cur_s->block_chain = NULL;
+ cur_s->block_length = 0;
+ do_free = 1;
+ }
+ // check the reassembled data length
+ if (asn_data_length < 1) {
+ pthread_mutex_unlock(&lowspeed->lock);
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ if (do_free)
+ free(data);
+ return -1;
+ }
+ // now, parse the data
+ uint8_t phase_id = data[0];
+
+ // tell the app
+ en50221_app_lowspeed_send_callback cb = lowspeed->send_callback;
+ void *cb_arg = lowspeed->send_callback_arg;
+ pthread_mutex_unlock(&lowspeed->lock);
+ int cbstatus = 0;
+ if (cb) {
+ cbstatus =
+ cb(cb_arg, slot_id, session_number, phase_id, data + 1, asn_data_length - 1);
+ }
+ // done
+ if (do_free)
+ free(data);
+ return cbstatus;
+}
diff --git a/lib/libdvben50221/en50221_app_lowspeed.h b/lib/libdvben50221/en50221_app_lowspeed.h
new file mode 100644
index 0000000..0ef983c
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_lowspeed.h
@@ -0,0 +1,219 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_LOWSPEED_H__
+#define __EN50221_APPLICATION_LOWSPEED_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+#include <libucsi/dvb/descriptor.h>
+
+#define COMMS_COMMAND_ID_CONNECT_ON_CHANNEL 0x01
+#define COMMS_COMMAND_ID_DISCONNECT_ON_CHANNEL 0x02
+#define COMMS_COMMAND_ID_SET_PARAMS 0x03
+#define COMMS_COMMAND_ID_ENQUIRE_STATUS 0x04
+#define COMMS_COMMAND_ID_GET_NEXT_BUFFER 0x05
+
+#define CONNECTION_DESCRIPTOR_TYPE_TELEPHONE 0x01
+#define CONNECTION_DESCRIPTOR_TYPE_CABLE 0x02
+
+#define COMMS_REPLY_ID_CONNECT_ACK 0x01
+#define COMMS_REPLY_ID_DISCONNECT_ACK 0x02
+#define COMMS_REPLY_ID_SET_PARAMS_ACK 0x03
+#define COMMS_REPLY_ID_STATUS_REPLY 0x04
+#define COMMS_REPLY_ID_GET_NEXT_BUFFER_ACK 0x05
+#define COMMS_REPLY_ID_SEND_ACK 0x06
+
+#define EN50221_APP_LOWSPEED_RESOURCEID(DEVICE_TYPE, DEVICE_NUMBER) MKRID(96,((DEVICE_TYPE)<<2)|((DEVICE_NUMBER) & 0x03),1)
+
+
+/**
+ * Structure holding information on a received comms command.
+ */
+struct en50221_app_lowspeed_command {
+ union {
+ struct {
+ uint8_t descriptor_type; // CONNECTION_DESCRIPTOR_TYPE_*
+ uint8_t retry_count;
+ uint8_t timeout;
+ union {
+ struct dvb_telephone_descriptor *telephone;
+ uint8_t cable_channel_id;
+ } descriptor;
+ } connect_on_channel;
+
+ struct {
+ uint8_t buffer_size;
+ uint8_t timeout;
+ } set_params;
+
+ struct {
+ uint8_t phase_id;
+ } get_next_buffer;
+ } u;
+};
+
+/**
+ * Type definition for command - called when we receive a comms command.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param command_id One of the COMMS_COMMAND_ID_* values
+ * @param command Pointer to a lowspeed command structure containing the command data.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_lowspeed_command_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t command_id,
+ struct en50221_app_lowspeed_command *command);
+
+/**
+ * Type definition for send - called when we receive data to send. The block can be segmented into
+ * multiple pieces - last_more indicates the details of this.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param phase_id Comms phase id.
+ * @param data The data.
+ * @param length Number of bytes.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_lowspeed_send_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t phase_id,
+ uint8_t *data,
+ uint32_t length);
+
+/**
+ * Opaque type representing a lowspeed resource.
+ */
+struct en50221_app_lowspeed;
+
+/**
+ * Create an instance of the lowspeed resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_lowspeed *
+ en50221_app_lowspeed_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the lowspeed resource.
+ *
+ * @param lowspeed Instance to destroy.
+ */
+extern void en50221_app_lowspeed_destroy(struct en50221_app_lowspeed *lowspeed);
+
+/**
+ * Informs the lowspeed object that a session to it has been closed - cleans up internal state.
+ *
+ * @param lowspeed lowspeed resource instance.
+ * @param session_number The session concerned.
+ */
+extern void en50221_app_lowspeed_clear_session(struct en50221_app_lowspeed *lowspeed,
+ uint16_t session_number);
+
+/**
+ * Register the callback for when we receive a comms command.
+ *
+ * @param lowspeed lowspeed resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_lowspeed_register_command_callback(struct en50221_app_lowspeed *lowspeed,
+ en50221_app_lowspeed_command_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive data to send.
+ *
+ * @param lowspeed lowspeed resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_lowspeed_register_send_callback(struct en50221_app_lowspeed *lowspeed,
+ en50221_app_lowspeed_send_callback callback,
+ void *arg);
+
+/**
+ * Send a comms reply to the CAM.
+ *
+ * @param lowspeed lowspeed resource instance.
+ * @param session_number Session number to send it on.
+ * @param comms_reply_id One of the COMMS_REPLY_ID_* values.
+ * @param return_value Comms reply specific value.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_lowspeed_send_comms_reply(struct en50221_app_lowspeed *lowspeed,
+ uint16_t session_number,
+ uint8_t comms_reply_id,
+ uint8_t return_value);
+
+/**
+ * Send received data to the CAM.
+ *
+ * @param lowspeed lowspeed resource instance.
+ * @param session_number Session number to send it on.
+ * @param phase_id Comms phase id.
+ * @param tx_data_length Length of data in bytes (max 254 bytes as per spec).
+ * @param tx_data Data.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_lowspeed_send_comms_data(struct en50221_app_lowspeed *lowspeed,
+ uint16_t session_number,
+ uint8_t phase_id,
+ uint32_t tx_data_length,
+ uint8_t * tx_data);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param lowspeed lowspeed instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_lowspeed_message(struct en50221_app_lowspeed *lowspeed,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_mmi.c b/lib/libdvben50221/en50221_app_mmi.c
new file mode 100644
index 0000000..830eaa3
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_mmi.c
@@ -0,0 +1,1397 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include <libucsi/dvb/types.h>
+#include "en50221_app_mmi.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_mmi_session {
+ uint16_t session_number;
+
+ uint8_t *menu_block_chain;
+ uint32_t menu_block_length;
+
+ uint8_t *list_block_chain;
+ uint32_t list_block_length;
+
+ uint8_t *subtitlesegment_block_chain;
+ uint32_t subtitlesegment_block_length;
+
+ uint8_t *subtitledownload_block_chain;
+ uint32_t subtitledownload_block_length;
+
+ struct en50221_app_mmi_session *next;
+};
+
+struct en50221_app_mmi {
+ struct en50221_app_send_functions *funcs;
+ struct en50221_app_mmi_session *sessions;
+
+ en50221_app_mmi_close_callback closecallback;
+ void *closecallback_arg;
+
+ en50221_app_mmi_display_control_callback displaycontrolcallback;
+ void *displaycontrolcallback_arg;
+
+ en50221_app_mmi_keypad_control_callback keypadcontrolcallback;
+ void *keypadcontrolcallback_arg;
+
+ en50221_app_mmi_subtitle_segment_callback subtitlesegmentcallback;
+ void *subtitlesegmentcallback_arg;
+
+ en50221_app_mmi_scene_end_mark_callback sceneendmarkcallback;
+ void *sceneendmarkcallback_arg;
+
+ en50221_app_mmi_scene_control_callback scenecontrolcallback;
+ void *scenecontrolcallback_arg;
+
+ en50221_app_mmi_subtitle_download_callback subtitledownloadcallback;
+ void *subtitledownloadcallback_arg;
+
+ en50221_app_mmi_flush_download_callback flushdownloadcallback;
+ void *flushdownloadcallback_arg;
+
+ en50221_app_mmi_enq_callback enqcallback;
+ void *enqcallback_arg;
+
+ en50221_app_mmi_menu_callback menucallback;
+ void *menucallback_arg;
+
+ en50221_app_mmi_list_callback listcallback;
+ void *listcallback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_mmi_parse_close(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_display_control(struct en50221_app_mmi
+ *mmi, uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_keypad_control(struct en50221_app_mmi
+ *mmi, uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_enq(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data, uint32_t data_length);
+static int en50221_app_mmi_parse_list_menu(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t tag_id, int more_last,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_subtitle(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t tag_id, int more_last,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_scene_end_mark(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_scene_control(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_subtitle(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t tag_id, int more_last,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_parse_flush_download(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_mmi_defragment(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint32_t tag_id, int more_last,
+ uint8_t * indata,
+ uint32_t indata_length,
+ uint8_t ** outdata,
+ uint32_t * outdata_length);
+static int en50221_app_mmi_defragment_text(uint8_t * data,
+ uint32_t data_length,
+ uint8_t ** outdata,
+ uint32_t * outdata_length,
+ uint32_t * outconsumed);
+
+
+
+struct en50221_app_mmi *en50221_app_mmi_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_mmi *mmi = NULL;
+
+ // create structure and set it up
+ mmi = malloc(sizeof(struct en50221_app_mmi));
+ if (mmi == NULL) {
+ return NULL;
+ }
+ mmi->funcs = funcs;
+ mmi->closecallback = NULL;
+ mmi->displaycontrolcallback = NULL;
+ mmi->keypadcontrolcallback = NULL;
+ mmi->subtitlesegmentcallback = NULL;
+ mmi->sceneendmarkcallback = NULL;
+ mmi->scenecontrolcallback = NULL;
+ mmi->subtitledownloadcallback = NULL;
+ mmi->flushdownloadcallback = NULL;
+ mmi->enqcallback = NULL;
+ mmi->menucallback = NULL;
+ mmi->listcallback = NULL;
+ mmi->sessions = NULL;
+
+ pthread_mutex_init(&mmi->lock, NULL);
+
+ // done
+ return mmi;
+}
+
+void en50221_app_mmi_destroy(struct en50221_app_mmi *mmi)
+{
+ struct en50221_app_mmi_session *cur_s = mmi->sessions;
+ while (cur_s) {
+ struct en50221_app_mmi_session *next = cur_s->next;
+ if (cur_s->menu_block_chain)
+ free(cur_s->menu_block_chain);
+ if (cur_s->list_block_chain)
+ free(cur_s->list_block_chain);
+ if (cur_s->subtitlesegment_block_chain)
+ free(cur_s->subtitlesegment_block_chain);
+ if (cur_s->subtitledownload_block_chain)
+ free(cur_s->subtitledownload_block_chain);
+ free(cur_s);
+ cur_s = next;
+ }
+
+ pthread_mutex_destroy(&mmi->lock);
+ free(mmi);
+}
+
+void en50221_app_mmi_clear_session(struct en50221_app_mmi *mmi,
+ uint16_t session_number)
+{
+ pthread_mutex_lock(&mmi->lock);
+ struct en50221_app_mmi_session *cur_s = mmi->sessions;
+ struct en50221_app_mmi_session *prev_s = NULL;
+ while (cur_s) {
+ if (cur_s->session_number == session_number) {
+ if (cur_s->menu_block_chain)
+ free(cur_s->menu_block_chain);
+ if (cur_s->list_block_chain)
+ free(cur_s->list_block_chain);
+ if (cur_s->subtitlesegment_block_chain)
+ free(cur_s->subtitlesegment_block_chain);
+ if (cur_s->subtitledownload_block_chain)
+ free(cur_s->subtitledownload_block_chain);
+ if (prev_s) {
+ prev_s->next = cur_s->next;
+ } else {
+ mmi->sessions = cur_s->next;
+ }
+ free(cur_s);
+ return;
+ }
+
+ prev_s = cur_s;
+ cur_s = cur_s->next;
+ }
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_close_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_close_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->closecallback = callback;
+ mmi->closecallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_display_control_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_display_control_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->displaycontrolcallback = callback;
+ mmi->displaycontrolcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_keypad_control_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_keypad_control_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->keypadcontrolcallback = callback;
+ mmi->keypadcontrolcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_subtitle_segment_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_subtitle_segment_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->subtitlesegmentcallback = callback;
+ mmi->subtitlesegmentcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_scene_end_mark_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_scene_end_mark_callback callback, void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->sceneendmarkcallback = callback;
+ mmi->sceneendmarkcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_scene_control_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_scene_control_callback callback, void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->scenecontrolcallback = callback;
+ mmi->scenecontrolcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_subtitle_download_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_subtitle_download_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->subtitledownloadcallback = callback;
+ mmi->subtitledownloadcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_flush_download_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_flush_download_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->flushdownloadcallback = callback;
+ mmi->flushdownloadcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_enq_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_enq_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->enqcallback = callback;
+ mmi->enqcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_menu_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_menu_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->menucallback = callback;
+ mmi->menucallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+void en50221_app_mmi_register_list_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_list_callback callback,
+ void *arg)
+{
+ pthread_mutex_lock(&mmi->lock);
+ mmi->listcallback = callback;
+ mmi->listcallback_arg = arg;
+ pthread_mutex_unlock(&mmi->lock);
+}
+
+int en50221_app_mmi_close(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t cmd_id, uint8_t delay)
+{
+ uint8_t data[6];
+ int data_length = 5;
+
+ data[0] = (TAG_CLOSE_MMI >> 16) & 0xFF;
+ data[1] = (TAG_CLOSE_MMI >> 8) & 0xFF;
+ data[2] = TAG_CLOSE_MMI & 0xFF;
+ data[3] = 1;
+ data[4] = cmd_id;
+ if (cmd_id == MMI_CLOSE_MMI_CMD_ID_DELAY) {
+ data[3] = 2;
+ data[5] = delay;
+ data_length = 6;
+ }
+ return mmi->funcs->send_data(mmi->funcs->arg, session_number, data,
+ data_length);
+}
+
+int en50221_app_mmi_display_reply(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t reply_id,
+ struct en50221_app_mmi_display_reply_details *details)
+{
+ uint8_t data[32];
+ struct iovec iov[2];
+ uint32_t iov_count;
+ int length_field_len;
+
+ // fill out the start of the header
+ data[0] = (TAG_DISPLAY_REPLY >> 16) & 0xFF;
+ data[1] = (TAG_DISPLAY_REPLY >> 8) & 0xFF;
+ data[2] = TAG_DISPLAY_REPLY & 0xFF;
+
+ switch (reply_id) {
+ case MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK:
+ data[3] = 2;
+ data[4] = reply_id;
+ data[5] = details->u.mode_ack.mmi_mode;
+ iov[0].iov_base = data;
+ iov[0].iov_len = 6;
+ iov_count = 1;
+ break;
+
+ case MMI_DISPLAY_REPLY_ID_LIST_DISPLAY_CHAR_TABLES:
+ case MMI_DISPLAY_REPLY_ID_LIST_INPUT_CHAR_TABLES:
+ if ((length_field_len =
+ asn_1_encode(details->u.char_table.table_length + 1, data + 3, 3)) < 0) {
+ return -1;
+ }
+ data[3 + length_field_len] = reply_id;
+ iov[0].iov_base = data;
+ iov[0].iov_len = 3 + length_field_len + 1;
+ iov[1].iov_base = details->u.char_table.table;
+ iov[1].iov_len = details->u.char_table.table_length;
+ iov_count = 2;
+ break;
+
+ case MMI_DISPLAY_REPLY_ID_LIST_OVERLAY_GFX_CHARACTERISTICS:
+ case MMI_DISPLAY_REPLY_ID_LIST_FULLSCREEN_GFX_CHARACTERISTICS:
+ {
+ if ((length_field_len =
+ asn_1_encode(1 + 9 + (details->u.gfx.num_pixel_depths * 2), data + 3, 3)) < 0) {
+ return -1;
+ }
+ data[3 + length_field_len] = reply_id;
+ data[3 + length_field_len + 1] = details->u.gfx.width >> 8;
+ data[3 + length_field_len + 2] = details->u.gfx.width;
+ data[3 + length_field_len + 3] = details->u.gfx.height >> 8;
+ data[3 + length_field_len + 4] = details->u.gfx.height;
+ data[3 + length_field_len + 5] =
+ ((details->u.gfx.aspect_ratio & 0x0f) << 4) |
+ ((details->u.gfx.gfx_relation_to_video & 0x07) << 1) |
+ (details->u.gfx.multiple_depths & 1);
+ data[3 + length_field_len + 6] = details->u.gfx.display_bytes >> 4;
+ data[3 + length_field_len + 7] =
+ ((details->u.gfx.display_bytes & 0x0f) << 4) |
+ ((details->u.gfx.composition_buffer_bytes & 0xf0) >> 4);
+ data[3 + length_field_len + 8] =
+ ((details->u.gfx.composition_buffer_bytes & 0x0f) << 4) |
+ ((details->u.gfx.object_cache_bytes & 0xf0) >> 4);
+ data[3 + length_field_len + 9] =
+ ((details->u.gfx.object_cache_bytes & 0x0f) << 4) |
+ (details->u.gfx.num_pixel_depths & 0x0f);
+
+ // render the pixel depths themselves
+ uint8_t *pixdepths =
+ alloca(details->u.gfx.num_pixel_depths * 2);
+ if (pixdepths == NULL) {
+ return -1;
+ }
+ uint32_t i;
+ for (i = 0; i < details->u.gfx.num_pixel_depths; i++) {
+ pixdepths[0] =
+ ((details->u.gfx.pixel_depths[i].display_depth & 0x07) << 5) |
+ ((details->u.gfx.pixel_depths[i].pixels_per_byte & 0x07) << 2);
+ pixdepths[1] =
+ details->u.gfx.pixel_depths[i].region_overhead;
+ pixdepths += 2;
+ }
+
+ // make up the iovs
+ iov[0].iov_base = data;
+ iov[0].iov_len = 3 + length_field_len + 10;
+ iov[1].iov_base = pixdepths;
+ iov[1].iov_len =
+ details->u.gfx.num_pixel_depths * 2;
+ iov_count = 2;
+ break;
+ }
+
+ default:
+ data[3] = 1;
+ data[4] = reply_id;
+ iov[0].iov_base = data;
+ iov[0].iov_len = 5;
+ iov_count = 1;
+ break;
+ }
+
+ // sendit
+ return mmi->funcs->send_datav(mmi->funcs->arg, session_number, iov, iov_count);
+}
+
+int en50221_app_mmi_keypress(struct en50221_app_mmi *mmi,
+ uint16_t session_number, uint8_t keycode)
+{
+ uint8_t data[5];
+
+ data[0] = (TAG_KEYPRESS >> 16) & 0xFF;
+ data[1] = (TAG_KEYPRESS >> 8) & 0xFF;
+ data[2] = TAG_KEYPRESS & 0xFF;
+ data[3] = 1;
+ data[4] = keycode;
+ return mmi->funcs->send_data(mmi->funcs->arg, session_number, data, 5);
+}
+
+int en50221_app_mmi_display_message(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t display_message_id)
+{
+ uint8_t data[5];
+
+ data[0] = (TAG_DISPLAY_MESSAGE >> 16) & 0xFF;
+ data[1] = (TAG_DISPLAY_MESSAGE >> 8) & 0xFF;
+ data[2] = TAG_DISPLAY_MESSAGE & 0xFF;
+ data[3] = 1;
+ data[4] = display_message_id;
+ return mmi->funcs->send_data(mmi->funcs->arg, session_number, data, 5);
+}
+
+int en50221_app_mmi_scene_done(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t decoder_continue,
+ uint8_t scene_reveal, uint8_t scene_tag)
+{
+ uint8_t data[5];
+
+ data[0] = (TAG_SCENE_DONE >> 16) & 0xFF;
+ data[1] = (TAG_SCENE_DONE >> 8) & 0xFF;
+ data[2] = TAG_SCENE_DONE & 0xFF;
+ data[3] = 1;
+ data[4] =
+ (decoder_continue ? 0x80 : 0x00) |
+ (scene_reveal ? 0x40 : 0x00) |
+ (scene_tag & 0x0f);
+ return mmi->funcs->send_data(mmi->funcs->arg, session_number, data, 5);
+}
+
+int en50221_app_mmi_download_reply(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint16_t object_id,
+ uint8_t download_reply_id)
+{
+ uint8_t data[7];
+
+ data[0] = (TAG_DOWNLOAD_REPLY >> 16) & 0xFF;
+ data[1] = (TAG_DOWNLOAD_REPLY >> 8) & 0xFF;
+ data[2] = TAG_DOWNLOAD_REPLY & 0xFF;
+ data[3] = 3;
+ data[4] = object_id >> 8;
+ data[5] = object_id;
+ data[6] = download_reply_id;
+ return mmi->funcs->send_data(mmi->funcs->arg, session_number, data, 7);
+}
+
+int en50221_app_mmi_answ(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t answ_id,
+ uint8_t * text, uint32_t text_count)
+{
+ uint8_t buf[10];
+
+ // set up the tag
+ buf[0] = (TAG_ANSWER >> 16) & 0xFF;
+ buf[1] = (TAG_ANSWER >> 8) & 0xFF;
+ buf[2] = TAG_ANSWER & 0xFF;
+
+ // encode the length field
+ struct iovec iov[2];
+ int length_field_len = 0;
+ int iov_count = 1;
+ if (answ_id == MMI_ANSW_ID_ANSWER) {
+ if ((length_field_len = asn_1_encode(text_count + 1, buf + 3, 3)) < 0) {
+ return -1;
+ }
+ buf[3 + length_field_len] = answ_id;
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 3 + length_field_len + 1;
+ iov[1].iov_base = text;
+ iov[1].iov_len = text_count;
+ iov_count = 2;
+ } else {
+ buf[3] = 1;
+ buf[4] = answ_id;
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 5;
+ iov_count = 1;
+ }
+
+ // create the data and send it
+ return mmi->funcs->send_datav(mmi->funcs->arg, session_number, iov,
+ iov_count);
+}
+
+int en50221_app_mmi_menu_answ(struct en50221_app_mmi *mmi,
+ uint16_t session_number, uint8_t choice_ref)
+{
+ uint8_t data[5];
+
+ data[0] = (TAG_MENU_ANSWER >> 16) & 0xFF;
+ data[1] = (TAG_MENU_ANSWER >> 8) & 0xFF;
+ data[2] = TAG_MENU_ANSWER & 0xFF;
+ data[3] = 1;
+ data[4] = choice_ref;
+ return mmi->funcs->send_data(mmi->funcs->arg, session_number, data, 5);
+}
+
+int en50221_app_mmi_message(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_CLOSE_MMI:
+ return en50221_app_mmi_parse_close(mmi, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_DISPLAY_CONTROL:
+ return en50221_app_mmi_parse_display_control(mmi, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_KEYPAD_CONTROL:
+ return en50221_app_mmi_parse_keypad_control(mmi, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_ENQUIRY:
+ return en50221_app_mmi_parse_enq(mmi, slot_id,
+ session_number, data + 3,
+ data_length - 3);
+ case TAG_MENU_LAST:
+ return en50221_app_mmi_parse_list_menu(mmi, slot_id,
+ session_number, tag,
+ 1, data + 3,
+ data_length - 3);
+ case TAG_MENU_MORE:
+ return en50221_app_mmi_parse_list_menu(mmi, slot_id,
+ session_number, tag,
+ 0, data + 3,
+ data_length - 3);
+ case TAG_LIST_LAST:
+ return en50221_app_mmi_parse_list_menu(mmi, slot_id,
+ session_number, tag,
+ 1, data + 3,
+ data_length - 3);
+ case TAG_LIST_MORE:
+ return en50221_app_mmi_parse_list_menu(mmi, slot_id,
+ session_number, tag,
+ 0, data + 3,
+ data_length - 3);
+ case TAG_SUBTITLE_SEGMENT_LAST:
+ return en50221_app_mmi_parse_subtitle(mmi, slot_id,
+ session_number, tag,
+ 1, data + 3,
+ data_length - 3);
+ case TAG_SUBTITLE_SEGMENT_MORE:
+ return en50221_app_mmi_parse_subtitle(mmi, slot_id,
+ session_number, tag,
+ 0, data + 3,
+ data_length - 3);
+ case TAG_SCENE_END_MARK:
+ return en50221_app_mmi_parse_scene_end_mark(mmi, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_SCENE_CONTROL:
+ return en50221_app_mmi_parse_scene_control(mmi, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_SUBTITLE_DOWNLOAD_LAST:
+ return en50221_app_mmi_parse_subtitle(mmi, slot_id,
+ session_number, tag,
+ 1, data + 3,
+ data_length - 3);
+ case TAG_SUBTITLE_DOWNLOAD_MORE:
+ return en50221_app_mmi_parse_subtitle(mmi, slot_id,
+ session_number, tag,
+ 0, data + 3,
+ data_length - 3);
+ case TAG_FLUSH_DOWNLOAD:
+ return en50221_app_mmi_parse_flush_download(mmi, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+
+
+static int en50221_app_mmi_parse_close(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length < 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] > (data_length - 1)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t cmd_id = data[1];
+ uint8_t delay = 0;
+ if (cmd_id == MMI_CLOSE_MMI_CMD_ID_DELAY) {
+ if (data[0] != 2) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ delay = data[2];
+ }
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_close_callback cb = mmi->closecallback;
+ void *cb_arg = mmi->closecallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, cmd_id, delay);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_parse_display_control(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length < 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] > (data_length - 1)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t cmd_id = data[1];
+ uint8_t mmi_mode = 0;
+ if (cmd_id == MMI_DISPLAY_CONTROL_CMD_ID_SET_MMI_MODE) {
+ if (data[0] != 2) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received short data\n");
+ return -1;
+ }
+ mmi_mode = data[2];
+ }
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_display_control_callback cb = mmi->displaycontrolcallback;
+ void *cb_arg = mmi->displaycontrolcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, cmd_id, mmi_mode);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_parse_keypad_control(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length < 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // skip over the length field
+ data += length_field_len;
+
+ // extract the information
+ uint8_t cmd_id = data[0];
+ uint8_t *keycodes = data + 1;
+
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_keypad_control_callback cb = mmi->keypadcontrolcallback;
+ void *cb_arg = mmi->keypadcontrolcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, cmd_id,
+ keycodes, asn_data_length - 1);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_parse_enq(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data, uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length < 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // skip over the length field
+ data += length_field_len;
+
+ // extract the information
+ uint8_t blind_answer = (data[0] & 0x01) ? 1 : 0;
+ uint8_t answer_length = data[1];
+ uint8_t *text = data + 2;
+
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_enq_callback cb = mmi->enqcallback;
+ void *cb_arg = mmi->enqcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, blind_answer,
+ answer_length, text, asn_data_length - 2);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_parse_list_menu(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t tag_id, int more_last,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ int result = 0;
+ uint8_t *text_flags = NULL;
+ struct en50221_app_mmi_text *text_data = NULL;
+ uint32_t i;
+ uint8_t text_count = 0;
+
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // skip over the length field
+ data += length_field_len;
+
+ // defragment
+ pthread_mutex_lock(&mmi->lock);
+ uint8_t *outdata;
+ uint32_t outdata_length;
+ int dfstatus =
+ en50221_app_mmi_defragment(mmi, session_number, tag_id,
+ more_last,
+ data, asn_data_length,
+ &outdata, &outdata_length);
+ if (dfstatus <= 0) {
+ pthread_mutex_unlock(&mmi->lock);
+ return dfstatus;
+ }
+ data = outdata;
+ data_length = outdata_length;
+
+ // check the reassembled data length
+ if (data_length < 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ pthread_mutex_unlock(&mmi->lock);
+ result = -1;
+ goto exit_cleanup;
+ }
+ // now, parse the data
+ uint8_t choice_nb = data[0];
+ text_count = choice_nb + 3;
+ if (choice_nb == 0xff)
+ text_count = 3;
+ data++;
+ data_length--;
+
+ // variables for extracted text state
+ text_flags = alloca(text_count);
+ if (text_flags == NULL) {
+ pthread_mutex_unlock(&mmi->lock);
+ result = -1;
+ goto exit_cleanup;
+ }
+ memset(text_flags, 0, text_count);
+ text_data = (struct en50221_app_mmi_text *)
+ alloca(sizeof(struct en50221_app_mmi_text) * text_count);
+ if (text_data == NULL) {
+ pthread_mutex_unlock(&mmi->lock);
+ result = -1;
+ goto exit_cleanup;
+ }
+ memset(text_data, 0,
+ sizeof(struct en50221_app_mmi_text) * text_count);
+
+ // extract the text!
+ for (i = 0; i < text_count; i++) {
+ uint32_t consumed = 0;
+ int cur_status =
+ en50221_app_mmi_defragment_text(data, data_length,
+ &text_data[i].text,
+ &text_data[i].text_length,
+ &consumed);
+ if (cur_status < 0) {
+ pthread_mutex_unlock(&mmi->lock);
+ result = -1;
+ goto exit_cleanup;
+ }
+
+ text_flags[i] = cur_status;
+ data += consumed;
+ data_length -= consumed;
+ }
+
+ // work out what to pass to the user
+ struct en50221_app_mmi_text *text_data_for_user = (struct en50221_app_mmi_text *)
+ alloca(sizeof(struct en50221_app_mmi_text) * text_count);
+ if (text_data_for_user == NULL) {
+ result = -1;
+ goto exit_cleanup;
+ }
+ memcpy(text_data_for_user, text_data,
+ sizeof(struct en50221_app_mmi_text) * text_count);
+ struct en50221_app_mmi_text *text_ptr = NULL;
+ if (text_count > 3) {
+ text_ptr = &text_data_for_user[3];
+ }
+ uint8_t *items_raw = NULL;
+ uint32_t items_raw_length = 0;
+ if (choice_nb == 0xff) {
+ items_raw = data;
+ items_raw_length = data_length;
+ }
+ // do callback
+ result = 0;
+ switch (tag_id) {
+ case TAG_MENU_LAST:
+ {
+ en50221_app_mmi_menu_callback cb = mmi->menucallback;
+ void *cb_arg = mmi->menucallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ result =
+ cb(cb_arg, slot_id, session_number,
+ &text_data_for_user[0],
+ &text_data_for_user[1],
+ &text_data_for_user[2],
+ text_count - 3, text_ptr,
+ items_raw_length, items_raw);
+ }
+ break;
+ }
+
+ case TAG_LIST_LAST:
+ {
+ en50221_app_mmi_list_callback cb = mmi->listcallback;
+ void *cb_arg = mmi->listcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ result =
+ cb(cb_arg, slot_id, session_number,
+ &text_data_for_user[0],
+ &text_data_for_user[1],
+ &text_data_for_user[2],
+ text_count - 3, text_ptr,
+ items_raw_length, items_raw);
+ }
+ break;
+ }
+
+ default:
+ pthread_mutex_unlock(&mmi->lock);
+ break;
+ }
+
+exit_cleanup:
+ if ((dfstatus == 2) && outdata)
+ free(outdata);
+ if (text_flags && text_data) {
+ for (i = 0; i < text_count; i++) {
+ if ((text_flags[i] == 2) && text_data[i].text) {
+ free(text_data[i].text);
+ }
+ }
+ }
+ return result;
+}
+
+static int en50221_app_mmi_parse_subtitle(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t tag_id, int more_last,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // skip over the length field
+ data += length_field_len;
+
+ // defragment
+ pthread_mutex_lock(&mmi->lock);
+ uint8_t *outdata;
+ uint32_t outdata_length;
+ int dfstatus =
+ en50221_app_mmi_defragment(mmi, session_number, tag_id,
+ more_last,
+ data, asn_data_length,
+ &outdata, &outdata_length);
+ if (dfstatus <= 0) {
+ pthread_mutex_unlock(&mmi->lock);
+ return dfstatus;
+ }
+ // do callback
+ int cbstatus = 0;
+ switch (tag_id) {
+ case TAG_SUBTITLE_SEGMENT_LAST:
+ {
+ en50221_app_mmi_subtitle_segment_callback cb =
+ mmi->subtitlesegmentcallback;
+ void *cb_arg = mmi->subtitlesegmentcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ cbstatus =
+ cb(cb_arg, slot_id, session_number, outdata, outdata_length);
+ }
+ break;
+ }
+
+ case TAG_SUBTITLE_DOWNLOAD_LAST:
+ {
+ en50221_app_mmi_subtitle_download_callback cb =
+ mmi->subtitledownloadcallback;
+ void *cb_arg = mmi->subtitledownloadcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ cbstatus =
+ cb(cb_arg, slot_id, session_number, outdata, outdata_length);
+ }
+ break;
+ }
+ }
+
+ // free the data returned by the defragment call if asked to
+ if (dfstatus == 2) {
+ free(outdata);
+ }
+ // done
+ return cbstatus;
+}
+
+static int en50221_app_mmi_parse_scene_end_mark(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t flags = data[1];
+
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_scene_end_mark_callback cb =
+ mmi->sceneendmarkcallback;
+ void *cb_arg = mmi->sceneendmarkcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ (flags & 0x80) ? 1 : 0,
+ (flags & 0x40) ? 1 : 0,
+ (flags & 0x20) ? 1 : 0, flags & 0x0f);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_parse_scene_control(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t flags = data[1];
+
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_scene_control_callback cb = mmi->scenecontrolcallback;
+ void *cb_arg = mmi->scenecontrolcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number,
+ (flags & 0x80) ? 1 : 0,
+ (flags & 0x40) ? 1 : 0, flags & 0x0f);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_parse_flush_download(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *data,
+ uint32_t data_length)
+{
+ // validate data
+ if (data_length != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 0) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ // tell the app
+ pthread_mutex_lock(&mmi->lock);
+ en50221_app_mmi_flush_download_callback cb = mmi->flushdownloadcallback;
+ void *cb_arg = mmi->flushdownloadcallback_arg;
+ pthread_mutex_unlock(&mmi->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number);
+ }
+ return 0;
+}
+
+static int en50221_app_mmi_defragment(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint32_t tag_id,
+ int more_last,
+ uint8_t * indata,
+ uint32_t indata_length,
+ uint8_t ** outdata,
+ uint32_t * outdata_length)
+{
+ struct en50221_app_mmi_session *cur_s = mmi->sessions;
+ while (cur_s) {
+ if (cur_s->session_number == session_number)
+ break;
+ cur_s = cur_s->next;
+ }
+
+ // more data is still to come
+ if (!more_last) {
+ // if there was no previous session, create one
+ if (cur_s == NULL) {
+ cur_s = malloc(sizeof(struct en50221_app_mmi_session));
+ if (cur_s == NULL) {
+ print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
+ return -1;
+ }
+ cur_s->session_number = session_number;
+ cur_s->menu_block_chain = NULL;
+ cur_s->menu_block_length = 0;
+ cur_s->list_block_chain = NULL;
+ cur_s->list_block_length = 0;
+ cur_s->subtitlesegment_block_chain = NULL;
+ cur_s->subtitlesegment_block_length = 0;
+ cur_s->subtitledownload_block_chain = NULL;
+ cur_s->subtitledownload_block_length = 0;
+ cur_s->next = mmi->sessions;
+ mmi->sessions = cur_s;
+ }
+ // find the block/block_length to use
+ uint8_t **block_chain;
+ uint32_t *block_length;
+ switch (tag_id) {
+ case TAG_MENU_LAST:
+ case TAG_MENU_MORE:
+ block_chain = &cur_s->menu_block_chain;
+ block_length = &cur_s->menu_block_length;
+ break;
+ case TAG_LIST_LAST:
+ case TAG_LIST_MORE:
+ block_chain = &cur_s->list_block_chain;
+ block_length = &cur_s->list_block_length;
+ break;
+ case TAG_SUBTITLE_SEGMENT_LAST:
+ case TAG_SUBTITLE_SEGMENT_MORE:
+ block_chain = &cur_s->subtitlesegment_block_chain;
+ block_length = &cur_s->subtitlesegment_block_length;
+ break;
+ case TAG_SUBTITLE_DOWNLOAD_LAST:
+ case TAG_SUBTITLE_DOWNLOAD_MORE:
+ block_chain = &cur_s->subtitledownload_block_chain;
+ block_length = &cur_s->subtitledownload_block_length;
+ break;
+ default:
+ return -1;
+ }
+
+ // append the data
+ uint8_t *new_data =
+ realloc(*block_chain, *block_length + indata_length);
+ if (new_data == NULL) {
+ print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
+ return -1;
+ }
+ memcpy(new_data + *block_length, indata, indata_length);
+ *block_chain = new_data;
+ *block_length += indata_length;
+
+ // success, but block not complete yet
+ return 0;
+ }
+ // we hit the last of a possible chain of fragments
+ if (cur_s != NULL) {
+ // find the block/block_length to use
+ uint8_t **block_chain;
+ uint32_t *block_length;
+ switch (tag_id) {
+ case TAG_MENU_LAST:
+ case TAG_MENU_MORE:
+ block_chain = &cur_s->menu_block_chain;
+ block_length = &cur_s->menu_block_length;
+ break;
+ case TAG_LIST_LAST:
+ case TAG_LIST_MORE:
+ block_chain = &cur_s->list_block_chain;
+ block_length = &cur_s->list_block_length;
+ break;
+ case TAG_SUBTITLE_SEGMENT_LAST:
+ case TAG_SUBTITLE_SEGMENT_MORE:
+ block_chain = &cur_s->subtitlesegment_block_chain;
+ block_length = &cur_s->subtitlesegment_block_length;
+ break;
+ case TAG_SUBTITLE_DOWNLOAD_LAST:
+ case TAG_SUBTITLE_DOWNLOAD_MORE:
+ block_chain = &cur_s->subtitledownload_block_chain;
+ block_length = &cur_s->subtitledownload_block_length;
+ break;
+ default:
+ return -1;
+ }
+
+ // we have a preceding fragment - need to append
+ uint8_t *new_data =
+ realloc(*block_chain, *block_length + indata_length);
+ if (new_data == NULL) {
+ print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
+ return -1;
+ }
+ memcpy(new_data + *block_length, indata, indata_length);
+ *outdata_length = *block_length + indata_length;
+ *outdata = new_data;
+ *block_chain = NULL;
+ *block_length = 0;
+
+ // success, and indicate to free the block when done
+ return 2;
+ }
+ // success, but indicate it is not to be freed
+ *outdata_length = indata_length;
+ *outdata = indata;
+ return 1;
+}
+
+static int en50221_app_mmi_defragment_text(uint8_t * data,
+ uint32_t data_length,
+ uint8_t ** outdata,
+ uint32_t * outdata_length,
+ uint32_t * outconsumed)
+{
+ uint8_t *text = NULL;
+ uint32_t text_length = 0;
+ uint32_t consumed = 0;
+
+ while (1) {
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Short data\n");
+ if (text)
+ free(text);
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+ data += 3;
+ data_length -= 3;
+ consumed += 3;
+
+ // get the length of the data and adjust
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len =
+ asn_1_decode(&asn_data_length, data,
+ data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ if (text)
+ free(text);
+ return -1;
+ }
+ data += length_field_len;
+ data_length -= length_field_len;
+ consumed += length_field_len;
+
+ // deal with the tags
+ if (tag == TAG_TEXT_LAST) {
+ if (text == NULL) {
+ *outdata = data;
+ *outdata_length = asn_data_length;
+ *outconsumed = consumed + asn_data_length;
+ return 1;
+ } else {
+ // append the data
+ uint8_t *new_text = realloc(text,
+ text_length + asn_data_length);
+ if (new_text == NULL) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Ran out of memory\n");
+ if (text)
+ free(text);
+ return -1;
+ }
+ memcpy(new_text + text_length, data,
+ asn_data_length);
+ *outdata = new_text;
+ *outdata_length =
+ text_length + asn_data_length;
+ *outconsumed = consumed + asn_data_length;
+ return 2;
+ }
+
+ } else if (tag == TAG_TEXT_MORE) {
+ // append the data
+ uint8_t *new_text =
+ realloc(text, text_length + asn_data_length);
+ if (new_text == NULL) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Ran out of memory\n");
+ if (text)
+ free(text);
+ return -1;
+ }
+ memcpy(new_text + text_length, data,
+ asn_data_length);
+ text = new_text;
+ text_length += asn_data_length;
+
+ // consume the data
+ data += asn_data_length;
+ data_length -= asn_data_length;
+ consumed += asn_data_length;
+ } else {
+ // unknown tag
+ print(LOG_LEVEL, ERROR, 1,
+ "Unknown MMI text tag\n");
+ if (text)
+ free(text);
+ return -1;
+ }
+ }
+}
diff --git a/lib/libdvben50221/en50221_app_mmi.h b/lib/libdvben50221/en50221_app_mmi.h
new file mode 100644
index 0000000..5c5b727
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_mmi.h
@@ -0,0 +1,618 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_mmi_H__
+#define __EN50221_APPLICATION_mmi_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_MMI_RESOURCEID MKRID(64,1,1)
+
+#define MMI_CLOSE_MMI_CMD_ID_IMMEDIATE 0x00
+#define MMI_CLOSE_MMI_CMD_ID_DELAY 0x01
+
+#define MMI_DISPLAY_CONTROL_CMD_ID_SET_MMI_MODE 0x01
+#define MMI_DISPLAY_CONTROL_CMD_ID_GET_DISPLAY_CHAR_TABLES 0x02
+#define MMI_DISPLAY_CONTROL_CMD_ID_GET_INPUT_CHAR_TABLES 0x03
+#define MMI_DISPLAY_CONTROL_CMD_ID_GET_OVERLAY_GFX_CHARACTERISTICS 0x04
+#define MMI_DISPLAY_CONTROL_CMD_ID_GET_FULLSCREEN_GFX_CHARACTERISTICS 0x05
+
+#define MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK 0x01
+#define MMI_DISPLAY_REPLY_ID_LIST_DISPLAY_CHAR_TABLES 0x02
+#define MMI_DISPLAY_REPLY_ID_LIST_INPUT_CHAR_TABLES 0x03
+#define MMI_DISPLAY_REPLY_ID_LIST_OVERLAY_GFX_CHARACTERISTICS 0x04
+#define MMI_DISPLAY_REPLY_ID_LIST_FULLSCREEN_GFX_CHARACTERISTICS 0x05
+#define MMI_DISPLAY_REPLY_ID_UNKNOWN_CMD_ID 0xF0
+#define MMI_DISPLAY_REPLY_ID_UNKNOWN_MMI_MODE 0xF1
+#define MMI_DISPLAY_REPLY_ID_UNKNOWN_CHAR_TABLE 0xF2
+
+#define MMI_MODE_HIGH_LEVEL 0x01
+#define MMI_MODE_LOW_LEVEL_OVERLAY_GFX 0x02
+#define MMI_MODE_LOW_LEVEL_FULLSCREEN_GFX 0x03
+
+#define MMI_KEYPAD_CONTROL_CMD_ID_INTERCEPT_ALL 0x01
+#define MMI_KEYPAD_CONTROL_CMD_ID_IGNORE_ALL 0x02
+#define MMI_KEYPAD_CONTROL_CMD_ID_INTERCEPT_SELECTED 0x03
+#define MMI_KEYPAD_CONTROL_CMD_ID_IGNORE_SELECTED 0x04
+#define MMI_KEYPAD_CONTROL_CMD_ID_REJECT_KEYPRESS 0x05
+
+#define MMI_GFX_VIDEO_RELATION_NONE 0x00
+#define MMI_GFX_VIDEO_RELATION_MATCHES_EXACTLY 0x07
+
+#define MMI_DISPLAY_MESSAGE_ID_OK 0x00
+#define MMI_DISPLAY_MESSAGE_ID_ERROR 0x01
+#define MMI_DISPLAY_MESSAGE_ID_OUT_OF_MEMORY 0x02
+#define MMI_DISPLAY_MESSAGE_ID_SUBTITLE_SYNTAX_ERROR 0x03
+#define MMI_DISPLAY_MESSAGE_ID_UNDEFINED_REGION 0x04
+#define MMI_DISPLAY_MESSAGE_ID_UNDEFINED_CLUT 0x05
+#define MMI_DISPLAY_MESSAGE_ID_UNDEFINED_OBJECT 0x06
+#define MMI_DISPLAY_MESSAGE_ID_INCOMPATABLE_OBJECT 0x07
+#define MMI_DISPLAY_MESSAGE_ID_UNKNOWN_CHARACTER 0x08
+#define MMI_DISPLAY_MESSAGE_ID_DISPLAY_CHANGED 0x09
+
+#define MMI_DOWNLOAD_REPLY_ID_OK 0x00
+#define MMI_DOWNLOAD_REPLY_ID_NOT_OBJECT_SEGMENT 0x01
+#define MMI_DOWNLOAD_REPLY_ID_OUT_OF_MEMORY 0x02
+
+#define MMI_ANSW_ID_CANCEL 0x00
+#define MMI_ANSW_ID_ANSWER 0x01
+
+/**
+ * A pixel depth as supplied with display_reply details
+ */
+struct en50221_app_mmi_pixel_depth {
+ uint8_t display_depth;
+ uint8_t pixels_per_byte;
+ uint8_t region_overhead;
+};
+
+/**
+ * Details returned with a display_reply
+ */
+struct en50221_app_mmi_display_reply_details {
+ union {
+ struct {
+ uint16_t width;
+ uint16_t height;
+ uint8_t aspect_ratio;
+ uint8_t gfx_relation_to_video; /* one of MMI_GFX_VIDEO_RELATION_* */
+ uint8_t multiple_depths;
+ uint16_t display_bytes;
+ uint8_t composition_buffer_bytes;
+ uint8_t object_cache_bytes;
+ uint8_t num_pixel_depths;
+ struct en50221_app_mmi_pixel_depth *pixel_depths;
+ } gfx; /* MMI_DISPLAY_REPLY_ID_LIST_OVERLAY_GFX_CHARACTERISTICS or
+ MMI_DISPLAY_REPLY_ID_LIST_FULLSCREEN_GFX_CHARACTERISTICS */
+
+ struct {
+ uint32_t table_length;
+ uint8_t *table;
+ } char_table; /* MMI_DISPLAY_REPLY_ID_LIST_DISPLAY_CHAR_TABLES or
+ MMI_DISPLAY_REPLY_ID_LIST_INPUT_CHAR_TABLES */
+
+ struct {
+ uint8_t mmi_mode; /* one of the MMI_MODE_* values */
+ } mode_ack; /* for MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK */
+ } u;
+};
+
+/**
+ * Pointer to a text string.
+ */
+struct en50221_app_mmi_text {
+ uint8_t *text;
+ uint32_t text_length;
+};
+
+/**
+ * Type definition for close - called when we receive an mmi_close from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param cmd_id One of the MMI_CLOSE_MMI_CMD_ID_* values.
+ * @param delay Delay supplied with MMI_CLOSE_MMI_CMD_ID_DELAY.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_close_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t cmd_id,
+ uint8_t delay);
+
+/**
+ * Type definition for display_control callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param cmd_id One of the MMI_DISPLAY_CONTROL_CMD_ID_* values.
+ * @param delay One of the MMI_MODE_* values.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_display_control_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t cmd_id,
+ uint8_t mmi_mode);
+
+/**
+ * Type definition for keypad_control callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param cmd_id One of the MMI_KEYPAD_CONTROL_CMD_ID_* values.
+ * @param key_codes Pointer to the key codes.
+ * @param key_codes_count Number of key codes.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_keypad_control_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t cmd_id,
+ uint8_t *key_codes,
+ uint32_t key_codes_count);
+
+/**
+ * Type definition for subtitle_segment callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param segment Pointer to the segment data.
+ * @param segment_size Size of segment data.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_subtitle_segment_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *segment,
+ uint32_t segment_size);
+
+/**
+ * Type definition for scene_end_mark callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param decoder_continue_flag
+ * @param scene_reveal_flag
+ * @param send_scene_done
+ * @param scene_tag
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_scene_end_mark_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t decoder_continue_flag,
+ uint8_t scene_reveal_flag,
+ uint8_t send_scene_done,
+ uint8_t scene_tag);
+
+/**
+ * Type definition for scene_control callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param decoder_continue_flag
+ * @param scene_reveal_flag
+ * @param scene_tag
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_scene_control_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t decoder_continue_flag,
+ uint8_t scene_reveal_flag,
+ uint8_t scene_tag);
+
+/**
+ * Type definition for subtitle_download callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param segment Pointer to the segment data.
+ * @param segment_size Size of segment data.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_subtitle_download_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *segment,
+ uint32_t segment_size);
+
+/**
+ * Type definition for flush_download callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_flush_download_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number);
+
+/**
+ * Type definition for enq callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param blind_answer 1=>Obscure text input in some manner,
+ * @param expected_answer_length Expected max number of characters to be returned.
+ * @param text Pointer to the text data.
+ * @param text_size Size of text data.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_enq_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t blind_answer,
+ uint8_t expected_answer_length,
+ uint8_t * text,
+ uint32_t text_size);
+
+/**
+ * Type definition for menu callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param title Title text.
+ * @param sub_title Sub-Title text.
+ * @param bottom Bottom text.
+ * @param item_count Number of text elements in items.
+ * @param items Pointer to array of en50221_app_mmi_text structures which are standard menu choices,
+ * @param item_raw_length Length of item raw data.
+ * @param items_raw If nonstandard items were supplied, pointer to their data.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_menu_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count,
+ struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length,
+ uint8_t *items_raw);
+
+/**
+ * Type definition for list callback.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param title Title text.
+ * @param sub_title Sub-Title text.
+ * @param bottom Bottom text.
+ * @param item_count Number of text elements in items.
+ * @param items Pointer to array of en50221_app_mmi_text structures which are standard menu choices,
+ * @param item_raw_length Length of item raw data.
+ * @param items_raw If nonstandard items were supplied, pointer to their data.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_mmi_list_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count,
+ struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length,
+ uint8_t *items_raw);
+
+/**
+ * Opaque type representing a mmi resource.
+ */
+struct en50221_app_mmi;
+
+/**
+ * Create an instance of the mmi resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_mmi *en50221_app_mmi_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the mmi resource.
+ *
+ * @param mmi Instance to destroy.
+ */
+extern void en50221_app_mmi_destroy(struct en50221_app_mmi *mmi);
+
+/**
+ * Informs the mmi object that a session to it has been closed - cleans up internal state.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number The session concerned.
+ */
+extern void en50221_app_mmi_clear_session(struct en50221_app_mmi *mmi,
+ uint16_t session_number);
+
+/**
+ * Register the callback for when we receive an mmi_close request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_close_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_close_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a display control request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_display_control_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_display_control_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a keypad control request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_keypad_control_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_keypad_control_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a subtitle segment request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_subtitle_segment_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_subtitle_segment_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a scene end mark request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_scene_end_mark_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_scene_end_mark_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a scene control request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_scene_control_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_scene_control_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a subtitle download request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_subtitle_download_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_subtitle_download_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a flush download request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_flush_download_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_flush_download_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive an enq request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_enq_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_enq_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a menu request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_menu_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_menu_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a list request.
+ *
+ * @param mmi mmi resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_mmi_register_list_callback(struct en50221_app_mmi *mmi,
+ en50221_app_mmi_list_callback callback,
+ void *arg);
+
+/**
+ * Send an mmi_close to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param cmd_id One of the MMI_CLOSE_MMI_CMD_ID_* values.
+ * @param delay Delay to use if MMI_CLOSE_MMI_CMD_ID_DELAY specified.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_close(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t cmd_id, uint8_t delay);
+
+/**
+ * Send a display_reply to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param reply_id One of the MMI_DISPLAY_REPLY_ID_* values.
+ * @param details The details of the reply - can be NULL if the chosen reply_id does not need it.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_display_reply(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t reply_id,
+ struct en50221_app_mmi_display_reply_details *details);
+
+/**
+ * Send a keypress to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param keycode The keycode.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_keypress(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t keycode);
+
+/**
+ * Send a display message to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param display_message_id One of the MMI_DISPLAY_MESSAGE_ID_* values.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_display_message(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t display_message_id);
+
+/**
+ * Send a scene done message to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param decoder_continue Copy of flag in scene_end_mark.
+ * @param scene_reveal Copy of flag in scene_end_mark.
+ * @param scene_tag Scene tag this responds to.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_scene_done(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t decoder_continue,
+ uint8_t scene_reveal,
+ uint8_t scene_tag);
+
+/**
+ * Send a download reply to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param object_id Object id.
+ * @param download_reply_id One of the MMI_DOWNLOAD_REPLY_ID_* values.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_download_reply(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint16_t object_id,
+ uint8_t download_reply_id);
+
+/**
+ * Send an answ to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param answ_id One of the MMI_ANSW_ID_* values.
+ * @param text The text if MMI_ANSW_ID_ANSWER.
+ * @param text_count Length of text.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_answ(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t answ_id,
+ uint8_t * text,
+ uint32_t text_count);
+
+/**
+ * Send a menu answ to the cam.
+ *
+ * @param mmi mmi resource instance.
+ * @param session_number Session number to send it on.
+ * @param choice_ref Option chosen by user (0=>canceled).
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_menu_answ(struct en50221_app_mmi *mmi,
+ uint16_t session_number,
+ uint8_t choice_ref);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param mmi mmi instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_mmi_message(struct en50221_app_mmi *mmi,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_rm.c b/lib/libdvben50221/en50221_app_rm.c
new file mode 100644
index 0000000..7a5bc2f
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_rm.c
@@ -0,0 +1,307 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include <libucsi/endianops.h>
+#include "en50221_app_rm.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_rm {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_rm_enq_callback enqcallback;
+ void *enqcallback_arg;
+
+ en50221_app_rm_reply_callback replycallback;
+ void *replycallback_arg;
+
+ en50221_app_rm_changed_callback changedcallback;
+ void *changedcallback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_rm_parse_profile_enq(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_rm_parse_profile_reply(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_app_rm_parse_profile_change(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+struct en50221_app_rm *en50221_app_rm_create(struct
+ en50221_app_send_functions
+ *funcs)
+{
+ struct en50221_app_rm *rm = NULL;
+
+ // create structure and set it up
+ rm = malloc(sizeof(struct en50221_app_rm));
+ if (rm == NULL) {
+ return NULL;
+ }
+ rm->funcs = funcs;
+ rm->enqcallback = NULL;
+ rm->replycallback = NULL;
+ rm->changedcallback = NULL;
+
+ pthread_mutex_init(&rm->lock, NULL);
+
+ // done
+ return rm;
+}
+
+void en50221_app_rm_destroy(struct en50221_app_rm *rm)
+{
+ pthread_mutex_destroy(&rm->lock);
+ free(rm);
+}
+
+void en50221_app_rm_register_enq_callback(struct en50221_app_rm *rm,
+ en50221_app_rm_enq_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&rm->lock);
+ rm->enqcallback = callback;
+ rm->enqcallback_arg = arg;
+ pthread_mutex_unlock(&rm->lock);
+}
+
+void en50221_app_rm_register_reply_callback(struct en50221_app_rm *rm,
+ en50221_app_rm_reply_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&rm->lock);
+ rm->replycallback = callback;
+ rm->replycallback_arg = arg;
+ pthread_mutex_unlock(&rm->lock);
+}
+
+void en50221_app_rm_register_changed_callback(struct en50221_app_rm *rm,
+ en50221_app_rm_changed_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&rm->lock);
+ rm->changedcallback = callback;
+ rm->changedcallback_arg = arg;
+ pthread_mutex_unlock(&rm->lock);
+}
+
+int en50221_app_rm_enq(struct en50221_app_rm *rm, uint16_t session_number)
+{
+ uint8_t buf[4];
+
+ // set up the tag
+ buf[0] = (TAG_PROFILE_ENQUIRY >> 16) & 0xFF;
+ buf[1] = (TAG_PROFILE_ENQUIRY >> 8) & 0xFF;
+ buf[2] = TAG_PROFILE_ENQUIRY & 0xFF;
+ buf[3] = 0;
+
+ // create the data and send it
+ return rm->funcs->send_data(rm->funcs->arg, session_number, buf, 4);
+}
+
+int en50221_app_rm_reply(struct en50221_app_rm *rm,
+ uint16_t session_number,
+ uint32_t resource_id_count,
+ uint32_t * resource_ids)
+{
+ uint8_t buf[10];
+
+ // set up the tag
+ buf[0] = (TAG_PROFILE >> 16) & 0xFF;
+ buf[1] = (TAG_PROFILE >> 8) & 0xFF;
+ buf[2] = TAG_PROFILE & 0xFF;
+
+ // encode the length field
+ int length_field_len;
+ if ((length_field_len = asn_1_encode(resource_id_count * 4, buf + 3, 3)) < 0) {
+ return -1;
+ }
+ // copy the data and byteswap it
+ uint32_t *copy_resource_ids = alloca(4 * resource_id_count);
+ if (copy_resource_ids == NULL) {
+ return -1;
+ }
+ uint8_t *data = (uint8_t *) copy_resource_ids;
+ memcpy(data, resource_ids, resource_id_count * 4);
+ uint32_t i;
+ for (i = 0; i < resource_id_count; i++) {
+ bswap32(data);
+ data += 4;
+ }
+
+ // build the iovecs
+ struct iovec iov[2];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 3 + length_field_len;
+ iov[1].iov_base = (uint8_t *) copy_resource_ids;
+ iov[1].iov_len = resource_id_count * 4;
+
+ // create the data and send it
+ return rm->funcs->send_datav(rm->funcs->arg, session_number, iov, 2);
+}
+
+int en50221_app_rm_changed(struct en50221_app_rm *rm,
+ uint16_t session_number)
+{
+ uint8_t buf[4];
+
+ // set up the tag
+ buf[0] = (TAG_PROFILE_CHANGE >> 16) & 0xFF;
+ buf[1] = (TAG_PROFILE_CHANGE >> 8) & 0xFF;
+ buf[2] = TAG_PROFILE_CHANGE & 0xFF;
+ buf[3] = 0;
+
+ // create the data and send it
+ return rm->funcs->send_data(rm->funcs->arg, session_number, buf, 4);
+}
+
+int en50221_app_rm_message(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ // dispatch it
+ switch (tag) {
+ case TAG_PROFILE_ENQUIRY:
+ return en50221_app_rm_parse_profile_enq(rm, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_PROFILE:
+ return en50221_app_rm_parse_profile_reply(rm, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_PROFILE_CHANGE:
+ return en50221_app_rm_parse_profile_change(rm, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+static int en50221_app_rm_parse_profile_enq(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ (void) data;
+ (void) data_length;
+
+ pthread_mutex_lock(&rm->lock);
+ en50221_app_rm_enq_callback cb = rm->enqcallback;
+ void *cb_arg = rm->enqcallback_arg;
+ pthread_mutex_unlock(&rm->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number);
+ }
+ return 0;
+}
+
+static int en50221_app_rm_parse_profile_reply(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t resources_count = asn_data_length / 4;
+ uint32_t *resource_ids = (uint32_t *) (data + length_field_len);
+ data += length_field_len;
+
+ // byteswap it
+ uint32_t i;
+ for (i = 0; i < resources_count; i++) {
+ bswap32(data);
+ data += 4;
+ }
+
+ // inform observer
+ pthread_mutex_lock(&rm->lock);
+ en50221_app_rm_reply_callback cb = rm->replycallback;
+ void *cb_arg = rm->replycallback_arg;
+ pthread_mutex_unlock(&rm->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, resources_count, resource_ids);
+ }
+ return 0;
+}
+
+static int en50221_app_rm_parse_profile_change(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ (void) data;
+ (void) data_length;
+
+ pthread_mutex_lock(&rm->lock);
+ en50221_app_rm_changed_callback cb = rm->changedcallback;
+ void *cb_arg = rm->changedcallback_arg;
+ pthread_mutex_unlock(&rm->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_rm.h b/lib/libdvben50221/en50221_app_rm.h
new file mode 100644
index 0000000..ec97372
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_rm.h
@@ -0,0 +1,187 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_RM_H__
+#define __EN50221_APPLICATION_RM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_RM_RESOURCEID MKRID(1,1,1)
+
+/**
+ * Type definition for profile_enq callback function - called when we receive
+ * a profile_enq from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_rm_enq_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number);
+
+/**
+ * Type definition for profile_reply callback function - called when we receive
+ * a profile_reply from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id_count Number of resource_ids.
+ * @param resource_ids The resource ids themselves.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_rm_reply_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id_count,
+ uint32_t *resource_ids);
+/**
+ * Type definition for profile_changed callback function - called when we receive
+ * a profile_changed from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_rm_changed_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number);
+
+
+
+/**
+ * Opaque type representing a resource manager.
+ */
+struct en50221_app_rm;
+
+/**
+ * Create an instance of the resource manager.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_rm *en50221_app_rm_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the resource manager.
+ *
+ * @param rm Instance to destroy.
+ */
+extern void en50221_app_rm_destroy(struct en50221_app_rm *rm);
+
+/**
+ * Register the callback for when we receive a profile_enq from a CAM.
+ *
+ * @param rm Resource manager instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_rm_register_enq_callback(struct en50221_app_rm *rm,
+ en50221_app_rm_enq_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a profile_reply from a CAM.
+ *
+ * @param rm Resource manager instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_rm_register_reply_callback(struct en50221_app_rm *rm,
+ en50221_app_rm_reply_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive a profile_changed from a CAM.
+ *
+ * @param rm Resource manager instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_rm_register_changed_callback(struct en50221_app_rm *rm,
+ en50221_app_rm_changed_callback callback,
+ void *arg);
+
+/**
+ * Send a profile_enq to a CAM.
+ *
+ * @param rm Resource manager resource instance.
+ * @param session_number Session number to send it on.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_rm_enq(struct en50221_app_rm *rm, uint16_t session_number);
+
+/**
+ * Send a profile_reply to a CAM.
+ *
+ * @param rm Resource manager resource instance.
+ * @param session_number Session number to send it on.
+ * @param resource_id_count Number of resource ids.
+ * @param resource_ids The resource IDs themselves
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_rm_reply(struct en50221_app_rm *rm,
+ uint16_t session_number,
+ uint32_t resource_id_count,
+ uint32_t * resource_ids);
+
+/**
+ * Send a profile_changed to a CAM.
+ *
+ * @param rm Resource manager resource instance.
+ * @param session_number Session number to send it on.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_rm_changed(struct en50221_app_rm *rm, uint16_t session_number);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param rm rm instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_rm_message(struct en50221_app_rm *rm,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_smartcard.c b/lib/libdvben50221/en50221_app_smartcard.c
new file mode 100644
index 0000000..763c6c4
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_smartcard.c
@@ -0,0 +1,296 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include "en50221_app_smartcard.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_smartcard {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_smartcard_command_callback command_callback;
+ void *command_callback_arg;
+
+ en50221_app_smartcard_send_callback send_callback;
+ void *send_callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_smartcard_parse_command(struct en50221_app_smartcard *smartcard,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+static int en50221_app_smartcard_parse_send(struct en50221_app_smartcard *smartcard,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+struct en50221_app_smartcard *en50221_app_smartcard_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_smartcard *smartcard = NULL;
+
+ // create structure and set it up
+ smartcard = malloc(sizeof(struct en50221_app_smartcard));
+ if (smartcard == NULL) {
+ return NULL;
+ }
+ smartcard->funcs = funcs;
+ smartcard->command_callback = NULL;
+ smartcard->send_callback = NULL;
+
+ pthread_mutex_init(&smartcard->lock, NULL);
+
+ // done
+ return smartcard;
+}
+
+void en50221_app_smartcard_destroy(struct en50221_app_smartcard *smartcard)
+{
+ pthread_mutex_destroy(&smartcard->lock);
+ free(smartcard);
+}
+
+void en50221_app_smartcard_register_command_callback(struct en50221_app_smartcard *smartcard,
+ en50221_app_smartcard_command_callback callback, void *arg)
+{
+ pthread_mutex_lock(&smartcard->lock);
+ smartcard->command_callback = callback;
+ smartcard->command_callback_arg = arg;
+ pthread_mutex_unlock(&smartcard->lock);
+}
+
+void en50221_app_smartcard_register_send_callback(struct en50221_app_smartcard *smartcard,
+ en50221_app_smartcard_send_callback callback, void *arg)
+{
+ pthread_mutex_lock(&smartcard->lock);
+ smartcard->send_callback = callback;
+ smartcard->send_callback_arg = arg;
+ pthread_mutex_unlock(&smartcard->lock);
+}
+
+int en50221_app_smartcard_command_reply(struct en50221_app_smartcard *smartcard,
+ uint16_t session_number,
+ uint8_t reply_id, uint8_t status,
+ uint8_t *data,
+ uint32_t data_length)
+{
+ uint8_t hdr[10];
+ struct iovec iovec[2];
+ int iov_count = 0;
+
+ // the tag
+ hdr[0] = (TAG_SMARTCARD_REPLY >> 16) & 0xFF;
+ hdr[1] = (TAG_SMARTCARD_REPLY >> 8) & 0xFF;
+ hdr[2] = TAG_SMARTCARD_REPLY & 0xFF;
+
+ // the rest of the data
+ if (reply_id == SMARTCARD_REPLY_ID_ANSW_TO_RESET) {
+ // encode the length field
+ int length_field_len;
+ if ((length_field_len = asn_1_encode(data_length + 2, data + 3, 3)) < 0) {
+ return -1;
+ }
+ // the rest of the header
+ hdr[3 + length_field_len] = reply_id;
+ hdr[3 + length_field_len + 1] = status;
+ iovec[0].iov_base = hdr;
+ iovec[0].iov_len = 3 + length_field_len + 2;
+
+ // the data
+ iovec[1].iov_base = data;
+ iovec[1].iov_len = data_length;
+ iov_count = 2;
+ } else {
+ hdr[3] = 2;
+ hdr[4] = reply_id;
+ hdr[5] = status;
+ iovec[0].iov_base = data;
+ iovec[0].iov_len = 6;
+ iov_count = 1;
+ }
+
+ return smartcard->funcs->send_datav(smartcard->funcs->arg, session_number, iovec, iov_count);
+}
+
+int en50221_app_smartcard_receive(struct en50221_app_smartcard *smartcard,
+ uint16_t session_number,
+ uint8_t *data,
+ uint32_t data_length,
+ uint8_t SW1, uint8_t SW2)
+{
+ uint8_t buf[10];
+ uint8_t trailer[10];
+
+ // set up the tag
+ buf[0] = (TAG_SMARTCARD_RCV >> 16) & 0xFF;
+ buf[1] = (TAG_SMARTCARD_RCV >> 8) & 0xFF;
+ buf[2] = TAG_SMARTCARD_RCV & 0xFF;
+
+ // encode the length field
+ int length_field_len;
+ if ((length_field_len = asn_1_encode(data_length + 2, buf + 3, 3)) < 0) {
+ return -1;
+ }
+ // set up the trailer
+ trailer[0] = SW1;
+ trailer[1] = SW2;
+
+ // build the iovecs
+ struct iovec iov[3];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 3 + length_field_len;
+ iov[1].iov_base = data;
+ iov[1].iov_len = data_length;
+ iov[2].iov_base = trailer;
+ iov[2].iov_len = 2;
+
+ // create the data and send it
+ return smartcard->funcs->send_datav(smartcard->funcs->arg,
+ session_number, iov, 3);
+}
+
+int en50221_app_smartcard_message(struct en50221_app_smartcard *smartcard,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t *data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_SMARTCARD_COMMAND:
+ return en50221_app_smartcard_parse_command(smartcard,
+ slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ case TAG_SMARTCARD_SEND:
+ return en50221_app_smartcard_parse_send(smartcard, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+
+
+
+
+
+static int en50221_app_smartcard_parse_command(struct en50221_app_smartcard *smartcard,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ if (data_length != 2) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (data[0] != 1) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t command_id = data[1];
+
+ // tell the app
+ pthread_mutex_lock(&smartcard->lock);
+ en50221_app_smartcard_command_callback cb = smartcard->command_callback;
+ void *cb_arg = smartcard->command_callback_arg;
+ pthread_mutex_unlock(&smartcard->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, command_id);
+ }
+ return 0;
+}
+
+static int en50221_app_smartcard_parse_send(struct en50221_app_smartcard *smartcard,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+ // check it
+ if (asn_data_length < 8) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ data += length_field_len;
+
+ // parse
+ uint8_t CLA = data[0];
+ uint8_t INS = data[1];
+ uint8_t P1 = data[2];
+ uint8_t P2 = data[3];
+ uint16_t length_in = (data[4] << 8) | data[5];
+ uint8_t *data_in = data + 6;
+
+ // validate the length
+ if ((length_in + 8) != asn_data_length) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint16_t length_out =
+ (data[6 + length_in] << 8) | data[6 + length_in + 1];
+
+ // tell the app
+ pthread_mutex_lock(&smartcard->lock);
+ en50221_app_smartcard_send_callback cb = smartcard->send_callback;
+ void *cb_arg = smartcard->send_callback_arg;
+ pthread_mutex_unlock(&smartcard->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, CLA, INS, P1,
+ P2, data_in, length_in, length_out);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_smartcard.h b/lib/libdvben50221/en50221_app_smartcard.h
new file mode 100644
index 0000000..bbad4a9
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_smartcard.h
@@ -0,0 +1,200 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_smartcard_H__
+#define __EN50221_APPLICATION_smartcard_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define SMARTCARD_COMMAND_ID_CONNECT 0x01
+#define SMARTCARD_COMMAND_ID_DISCONNECT 0x02
+#define SMARTCARD_COMMAND_ID_POWERON_CARD 0x03
+#define SMARTCARD_COMMAND_ID_POWEROFF_CARD 0x04
+#define SMARTCARD_COMMAND_ID_RESET_CARD 0x05
+#define SMARTCARD_COMMAND_ID_RESET_STATUS 0x06
+#define SMARTCARD_COMMAND_ID_READ_ANSW_TO_RESET 0x07
+
+#define SMARTCARD_REPLY_ID_CONNECTED 0x01
+#define SMARTCARD_REPLY_ID_FREE 0x02
+#define SMARTCARD_REPLY_ID_BUSY 0x03
+#define SMARTCARD_REPLY_ID_ANSW_TO_RESET 0x04
+#define SMARTCARD_REPLY_ID_NO_ANSW_TO_RESET 0x05
+
+#define SMARTCARD_STATUS_CARD_INSERTED 0x01
+#define SMARTCARD_STATUS_CARD_REMOVED 0x02
+#define SMARTCARD_STATUS_CARD_IN_PLACE_POWEROFF 0x03
+#define SMARTCARD_STATUS_CARD_IN_PLACE_POWERON 0x04
+#define SMARTCARD_STATUS_CARD_NO_CARD 0x05
+#define SMARTCARD_STATUS_CARD_UNRESPONSIVE_CARD 0x06
+#define SMARTCARD_STATUS_CARD_REFUSED_CARD 0x07
+
+#define EN50221_APP_SMARTCARD_RESOURCEID(DEVICE_NUMBER) MKRID(112, ((DEVICE_NUMBER)& 0x0f), 1)
+
+
+
+/**
+ * Type definition for command - called when we receive a command.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param command_id One of the SMARTCARD_COMMAND_ID_* values
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_smartcard_command_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t command_id);
+
+/**
+ * Type definition for command - called when we receive a send command.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param CLA CLA value.
+ * @param INS INS value.
+ * @param P1 P1 value.
+ * @param P2 P2 value.
+ * @param in Data to send to the card
+ * @param in_length Number of bytes to send.
+ * @param out_length Number of bytes expected.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_smartcard_send_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t CLA,
+ uint8_t INS,
+ uint8_t P1,
+ uint8_t P2,
+ uint8_t *in,
+ uint32_t in_length,
+ uint32_t out_length);
+
+/**
+ * Opaque type representing a smartcard resource.
+ */
+struct en50221_app_smartcard;
+
+/**
+ * Create an instance of the smartcard resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_smartcard *
+ en50221_app_smartcard_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the smartcard resource.
+ *
+ * @param smartcard Instance to destroy.
+ */
+extern void en50221_app_smartcard_destroy(struct en50221_app_smartcard *smartcard);
+
+/**
+ * Register the callback for when we receive a comms command.
+ *
+ * @param smartcard smartcard resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_smartcard_register_command_callback(struct en50221_app_smartcard *smartcard,
+ en50221_app_smartcard_command_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for when we receive data to send.
+ *
+ * @param smartcard smartcard resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_smartcard_register_send_callback(struct en50221_app_smartcard *smartcard,
+ en50221_app_smartcard_send_callback callback,
+ void *arg);
+
+/**
+ * Send a command response to the CAM.
+ *
+ * @param smartcard smartcard resource instance.
+ * @param session_number Session number to send it on.
+ * @param reply_id One of the SMARTCARD_REPLY_ID_* values.
+ * @param status One of the SMARTCARD_STATUS_* values.
+ * @param data Data to send when it is a SMARTCARD_REPLY_ID_ANSW_TO_RESET.
+ * @param data_length Length of data to send.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_smartcard_command_reply(struct en50221_app_smartcard *smartcard,
+ uint16_t session_number,
+ uint8_t reply_id,
+ uint8_t status,
+ uint8_t * data,
+ uint32_t data_length);
+
+/**
+ * Send data received from a smartcart to the CAM.
+ *
+ * @param smartcard smartcard resource instance.
+ * @param session_number Session number to send it on.
+ * @param data Data to send when it is a SMARTCARD_REPLY_ID_ANSW_TO_RESET.
+ * @param data_length Length of data to send.
+ * @param SW1 SW1 value.
+ * @param SW2 SW2 value.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_smartcard_receive(struct en50221_app_smartcard *smartcard,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length,
+ uint8_t SW1, uint8_t SW2);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param smartcard smartcard instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_smartcard_message(struct en50221_app_smartcard *smartcard,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_tags.h b/lib/libdvben50221/en50221_app_tags.h
new file mode 100644
index 0000000..0f5c2fc
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_tags.h
@@ -0,0 +1,104 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APP_TAGS_H__
+#define __EN50221_APP_TAGS_H__
+
+/* Resource Manager */
+#define TAG_PROFILE_ENQUIRY 0x9f8010
+#define TAG_PROFILE 0x9f8011
+#define TAG_PROFILE_CHANGE 0x9f8012
+
+/* Application Info */
+#define TAG_APP_INFO_ENQUIRY 0x9f8020
+#define TAG_APP_INFO 0x9f8021
+#define TAG_ENTER_MENU 0x9f8022
+
+/* CA Support */
+#define TAG_CA_INFO_ENQUIRY 0x9f8030
+#define TAG_CA_INFO 0x9f8031
+#define TAG_CA_PMT 0x9f8032
+#define TAG_CA_PMT_REPLY 0x9f8033
+
+/* Host Control */
+#define TAG_TUNE 0x9f8400
+#define TAG_REPLACE 0x9f8401
+#define TAG_CLEAR_REPLACE 0x9f8402
+#define TAG_ASK_RELEASE 0x9f8403
+
+/* Date and Time */
+#define TAG_DATE_TIME_ENQUIRY 0x9f8440
+#define TAG_DATE_TIME 0x9f8441
+
+/* Man Machine Interface (MMI) */
+#define TAG_CLOSE_MMI 0x9f8800
+#define TAG_DISPLAY_CONTROL 0x9f8801
+#define TAG_DISPLAY_REPLY 0x9f8802
+#define TAG_TEXT_LAST 0x9f8803
+#define TAG_TEXT_MORE 0x9f8804
+#define TAG_KEYPAD_CONTROL 0x9f8805
+#define TAG_KEYPRESS 0x9f8806
+#define TAG_ENQUIRY 0x9f8807
+#define TAG_ANSWER 0x9f8808
+#define TAG_MENU_LAST 0x9f8809
+#define TAG_MENU_MORE 0x9f880a
+#define TAG_MENU_ANSWER 0x9f880b
+#define TAG_LIST_LAST 0x9f880c
+#define TAG_LIST_MORE 0x9f880d
+#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e
+#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f
+#define TAG_DISPLAY_MESSAGE 0x9f8810
+#define TAG_SCENE_END_MARK 0x9f8811
+#define TAG_SCENE_DONE 0x9f8812
+#define TAG_SCENE_CONTROL 0x9f8813
+#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814
+#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815
+#define TAG_FLUSH_DOWNLOAD 0x9f8816
+#define TAG_DOWNLOAD_REPLY 0x9f8817
+
+/* Low Speed Communications */
+#define TAG_COMMS_COMMAND 0x9f8c00
+#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01
+#define TAG_COMMS_REPLY 0x9f8c02
+#define TAG_COMMS_SEND_LAST 0x9f8c03
+#define TAG_COMMS_SEND_MORE 0x9f8c04
+#define TAG_COMMS_RECV_LAST 0x9f8c05
+#define TAG_COMMS_RECV_MORE 0x9f8c06
+
+/* Authentication */
+#define TAG_AUTH_REQ 0x9f8200
+#define TAG_AUTH_RESP 0x9f8201
+
+/* Teletext */
+#define TAG_TELETEXT_EBU 0x9f9000
+
+/* Smartcard */
+#define TAG_SMARTCARD_COMMAND 0x9f8e00
+#define TAG_SMARTCARD_REPLY 0x9f8e01
+#define TAG_SMARTCARD_SEND 0x9f8e02
+#define TAG_SMARTCARD_RCV 0x9f8e03
+
+/* EPG */
+#define TAG_EPG_ENQUIRY 0x9f8f00
+#define TAG_EPG_REPLY 0x9f8f01
+
+#endif
diff --git a/lib/libdvben50221/en50221_app_teletext.c b/lib/libdvben50221/en50221_app_teletext.c
new file mode 100644
index 0000000..b839407
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_teletext.c
@@ -0,0 +1,141 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <pthread.h>
+#include "en50221_app_teletext.h"
+#include "en50221_app_tags.h"
+#include "asn_1.h"
+
+struct en50221_app_teletext {
+ struct en50221_app_send_functions *funcs;
+
+ en50221_app_teletext_callback callback;
+ void *callback_arg;
+
+ pthread_mutex_t lock;
+};
+
+static int en50221_app_teletext_parse_ebu(struct en50221_app_teletext *teletext,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t * data,
+ uint32_t data_length);
+
+
+
+struct en50221_app_teletext *
+ en50221_app_teletext_create(struct en50221_app_send_functions *funcs)
+{
+ struct en50221_app_teletext *teletext = NULL;
+
+ // create structure and set it up
+ teletext = malloc(sizeof(struct en50221_app_teletext));
+ if (teletext == NULL) {
+ return NULL;
+ }
+ teletext->funcs = funcs;
+ teletext->callback = NULL;
+
+ pthread_mutex_init(&teletext->lock, NULL);
+
+ // done
+ return teletext;
+}
+
+void en50221_app_teletext_destroy(struct en50221_app_teletext *teletext)
+{
+ pthread_mutex_destroy(&teletext->lock);
+ free(teletext);
+}
+
+void en50221_app_teletext_register_callback(struct en50221_app_teletext *teletext,
+ en50221_app_teletext_callback callback, void *arg)
+{
+ pthread_mutex_lock(&teletext->lock);
+ teletext->callback = callback;
+ teletext->callback_arg = arg;
+ pthread_mutex_unlock(&teletext->lock);
+}
+
+int en50221_app_teletext_message(struct en50221_app_teletext *teletext,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data, uint32_t data_length)
+{
+ (void) resource_id;
+
+ // get the tag
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
+
+ switch (tag) {
+ case TAG_TELETEXT_EBU:
+ return en50221_app_teletext_parse_ebu(teletext, slot_id,
+ session_number,
+ data + 3,
+ data_length - 3);
+ }
+
+ print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
+ return -1;
+}
+
+
+static int en50221_app_teletext_parse_ebu(struct en50221_app_teletext *teletext,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *data,
+ uint32_t data_length)
+{
+ // first of all, decode the length field
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
+ print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
+ return -1;
+ }
+
+ // check it
+ if (asn_data_length > (data_length - length_field_len)) {
+ print(LOG_LEVEL, ERROR, 1, "Received short data\n");
+ return -1;
+ }
+ uint8_t *teletext_data = data + length_field_len;
+
+ // tell the app
+ pthread_mutex_lock(&teletext->lock);
+ en50221_app_teletext_callback cb = teletext->callback;
+ void *cb_arg = teletext->callback_arg;
+ pthread_mutex_unlock(&teletext->lock);
+ if (cb) {
+ return cb(cb_arg, slot_id, session_number, teletext_data,
+ asn_data_length);
+ }
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_app_teletext.h b/lib/libdvben50221/en50221_app_teletext.h
new file mode 100644
index 0000000..b5b85f1
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_teletext.h
@@ -0,0 +1,107 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APPLICATION_teletext_H__
+#define __EN50221_APPLICATION_teletext_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_app_utils.h>
+
+#define EN50221_APP_TELETEXT_RESOURCEID MKRID(128, 1, 1)
+
+
+/**
+ * Type definition for request - called when we receive teletext from a CAM.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number concerned.
+ * @param teletext_data Data for the request.
+ * @param teletext_data_lenghth Number of bytes.
+ * @return 0 on success, -1 on failure.
+ */
+typedef int (*en50221_app_teletext_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint8_t *teletext_data,
+ uint32_t teletext_data_length);
+
+/**
+ * Opaque type representing a teletext resource.
+ */
+struct en50221_app_teletext;
+
+/**
+ * Create an instance of the teletext resource.
+ *
+ * @param funcs Send functions to use.
+ * @return Instance, or NULL on failure.
+ */
+extern struct en50221_app_teletext *
+ en50221_app_teletext_create(struct en50221_app_send_functions *funcs);
+
+/**
+ * Destroy an instance of the teletext resource.
+ *
+ * @param teletext Instance to destroy.
+ */
+extern void en50221_app_teletext_destroy(struct en50221_app_teletext *teletext);
+
+/**
+ * Register the callback for when we receive a request.
+ *
+ * @param teletext teletext resource instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_app_teletext_register_callback(struct en50221_app_teletext *teletext,
+ en50221_app_teletext_callback callback,
+ void *arg);
+
+/**
+ * Pass data received for this resource into it for parsing.
+ *
+ * @param teletext teletext instance.
+ * @param slot_id Slot ID concerned.
+ * @param session_number Session number concerned.
+ * @param resource_id Resource ID concerned.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, -1 on failure.
+ */
+extern int en50221_app_teletext_message(struct en50221_app_teletext *teletext,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data,
+ uint32_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_app_utils.c b/lib/libdvben50221/en50221_app_utils.c
new file mode 100644
index 0000000..df2632a
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_utils.c
@@ -0,0 +1,38 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "en50221_app_utils.h"
+
+struct en50221_app_public_resource_id
+ *en50221_app_decode_public_resource_id(struct en50221_app_public_resource_id *idf,
+ uint32_t resource_id)
+{
+ // reject private resources
+ if ((resource_id & 0xc0000000) == 0xc0000000)
+ return NULL;
+
+ idf->resource_class = (resource_id >> 16) & 0xffff; // use the resource_id as the MSBs of class
+ idf->resource_type = (resource_id >> 6) & 0x3ff;
+ idf->resource_version = resource_id & 0x3f;
+ return idf;
+}
diff --git a/lib/libdvben50221/en50221_app_utils.h b/lib/libdvben50221/en50221_app_utils.h
new file mode 100644
index 0000000..5c64760
--- /dev/null
+++ b/lib/libdvben50221/en50221_app_utils.h
@@ -0,0 +1,112 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __EN50221_APP_UTILS_H__
+#define __EN50221_APP_UTILS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/uio.h>
+
+/**
+ * A decomposed public resource structure.
+ *
+ * we will ignore private resource (resource_id_type==3),
+ * because they are not used by any modules at all and
+ * would need special code for any private resource anyway.
+ */
+struct en50221_app_public_resource_id {
+ uint16_t resource_class;
+ uint16_t resource_type;
+ uint8_t resource_version;
+};
+
+typedef int (*en50221_send_data) (void *arg,
+ uint16_t session_number,
+ uint8_t * data,
+ uint16_t data_length);
+typedef int (*en50221_send_datav) (void *arg,
+ uint16_t session_number,
+ struct iovec * vector,
+ int iov_count);
+
+/**
+ * An abstraction away from hardcoded send functions so different layers may be
+ * slotted in under the application layer.
+ */
+struct en50221_app_send_functions {
+ /**
+ * Argument to pass to these functions.
+ */
+ void *arg;
+
+ /**
+ * Send data.
+ */
+ en50221_send_data send_data;
+
+ /**
+ * Send vector data.
+ */
+ en50221_send_datav send_datav;
+};
+
+/**
+ * Make a host-endian uint32_t formatted resource id.
+ *
+ * @param CLASS Class of resource.
+ * @param TYPE Type of resource.
+ * @param VERSION Version of resource.
+ * @return Formatted resource id.
+ */
+#define MKRID(CLASS, TYPE, VERSION) ((((CLASS)&0xffff)<<16) | (((TYPE)&0x3ff)<<6) | ((VERSION)&0x3f))
+
+/**
+ * Decode a host-endian public resource_id into an en50221_app_public_resource_id structure.
+ *
+ * @param idf Structure to write decoded resource_id into.
+ * @param resource_id ID to decode.
+ * @return Pointer to idf on success, or NULL if this is not a public resource.
+ */
+struct en50221_app_public_resource_id *
+ en50221_app_decode_public_resource_id(struct en50221_app_public_resource_id *idf,
+ uint32_t resource_id);
+
+/**
+ * Encode an en50221_app_public_resource_id structure into a host-endian uint32_t.
+ *
+ * @param idf Structure to encode.
+ * @return The encoded value
+ */
+static inline uint32_t en50221_app_encode_public_resource_id(struct en50221_app_public_resource_id *idf) {
+ return MKRID(idf->resource_class, idf->resource_type, idf->resource_version);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_errno.h b/lib/libdvben50221/en50221_errno.h
new file mode 100644
index 0000000..0b53087
--- /dev/null
+++ b/lib/libdvben50221/en50221_errno.h
@@ -0,0 +1,49 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 session layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef EN50221_ERRNO
+#define EN50221_ERRNO 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EN50221ERR_CAREAD -1 /* error during read from CA device. */
+#define EN50221ERR_CAWRITE -2 /* error during write to CA device. */
+#define EN50221ERR_TIMEOUT -3 /* timeout occured waiting for a response from a device. */
+#define EN50221ERR_BADSLOTID -4 /* bad slot ID supplied by user - the offending slot_id will not be set. */
+#define EN50221ERR_BADCONNECTIONID -5 /* bad connection ID supplied by user. */
+#define EN50221ERR_BADSTATE -6 /* slot/connection in the wrong state. */
+#define EN50221ERR_BADCAMDATA -7 /* CAM supplied an invalid request. */
+#define EN50221ERR_OUTOFMEMORY -8 /* memory allocation failed. */
+#define EN50221ERR_ASNENCODE -9 /* ASN.1 encode failure - indicates library bug. */
+#define EN50221ERR_OUTOFCONNECTIONS -10 /* no more connections available. */
+#define EN50221ERR_OUTOFSLOTS -11 /* no more slots available - the offending slot_id will not be set. */
+#define EN50221ERR_IOVLIMIT -12 /* Too many struct iovecs were used. */
+#define EN50221ERR_BADSESSIONNUMBER -13 /* Bad session number suppplied by user. */
+#define EN50221ERR_OUTOFSESSIONS -14 /* no more sessions available. */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_session.c b/lib/libdvben50221/en50221_session.c
new file mode 100644
index 0000000..3fb9902
--- /dev/null
+++ b/lib/libdvben50221/en50221_session.c
@@ -0,0 +1,1055 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <time.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <sys/uio.h>
+#include <pthread.h>
+#include "en50221_transport.h"
+#include "en50221_session.h"
+#include "en50221_errno.h"
+#include "asn_1.h"
+
+
+// these are the possible session statuses
+#define S_STATUS_OPEN 0x00 // session is opened
+#define S_STATUS_CLOSE_NO_RES 0xF0 // could not open session, no proper resource available
+#define S_STATUS_CLOSE_RES_UNAVAILABLE 0xF1 // could not open session, resource unavailable
+#define S_STATUS_CLOSE_RES_LOW_VERSION 0xF2 // could not open session, resource version too low
+#define S_STATUS_CLOSE_RES_BUSY 0xF3 // could not open session, resource is busy
+
+#define ST_OPEN_SESSION_REQ 0x91 // h<--m
+#define ST_OPEN_SESSION_RES 0x92 // h-->m
+#define ST_CREATE_SESSION 0x93 // h-->m
+#define ST_CREATE_SESSION_RES 0x94 // h<--m
+#define ST_CLOSE_SESSION_REQ 0x95 // h<->m
+#define ST_CLOSE_SESSION_RES 0x96 // h<->m
+#define ST_SESSION_NUMBER 0x90 // h<->m
+
+#define S_STATE_IDLE 0x01 // this session is not in use
+#define S_STATE_ACTIVE 0x02 // this session is in use
+#define S_STATE_IN_CREATION 0x04 // this session waits for a ST_CREATE_SESSION_RES to become active
+#define S_STATE_IN_DELETION 0x08 // this session waits for ST_CLOSE_SESSION_RES to become idle again
+
+
+// for each session we store its identifier, the resource-id
+// it is linked to and the callback of the specific resource
+struct en50221_session {
+ uint8_t state;
+ uint32_t resource_id;
+ uint8_t slot_id;
+ uint8_t connection_id;
+
+ en50221_sl_resource_callback callback;
+ void *callback_arg;
+
+ pthread_mutex_t session_lock;
+};
+
+struct en50221_session_layer {
+ uint32_t max_sessions;
+ struct en50221_transport_layer *tl;
+
+ en50221_sl_lookup_callback lookup;
+ void *lookup_arg;
+
+ en50221_sl_session_callback session;
+ void *session_arg;
+
+ pthread_mutex_t global_lock;
+ pthread_mutex_t setcallback_lock;
+
+ int error;
+
+ struct en50221_session *sessions;
+};
+
+static void en50221_sl_transport_callback(void *arg, int reason,
+ uint8_t * data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id);
+static int en50221_sl_alloc_new_session(struct en50221_session_layer *sl,
+ uint32_t resource_id,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ en50221_sl_resource_callback
+ callback, void *arg);
+
+
+
+
+struct en50221_session_layer *en50221_sl_create(struct en50221_transport_layer *tl,
+ uint32_t max_sessions)
+{
+ struct en50221_session_layer *sl = NULL;
+ uint32_t i;
+
+ // setup structure
+ sl = (struct en50221_session_layer *)
+ malloc(sizeof(struct en50221_session_layer));
+ if (sl == NULL)
+ goto error_exit;
+ sl->max_sessions = max_sessions;
+ sl->lookup = NULL;
+ sl->session = NULL;
+ sl->tl = tl;
+ sl->error = 0;
+
+ // init the mutex
+ pthread_mutex_init(&sl->global_lock, NULL);
+ pthread_mutex_init(&sl->setcallback_lock, NULL);
+
+ // create the slots
+ sl->sessions = malloc(sizeof(struct en50221_session) * max_sessions);
+ if (sl->sessions == NULL)
+ goto error_exit;
+
+ // set them up
+ for (i = 0; i < max_sessions; i++) {
+ sl->sessions[i].state = S_STATE_IDLE;
+ sl->sessions[i].callback = NULL;
+
+ pthread_mutex_init(&sl->sessions[i].session_lock, NULL);
+ }
+
+ // register ourselves with the transport layer
+ en50221_tl_register_callback(tl, en50221_sl_transport_callback, sl);
+
+ return sl;
+
+error_exit:
+ en50221_sl_destroy(sl);
+ return NULL;
+}
+
+void en50221_sl_destroy(struct en50221_session_layer *sl)
+{
+ uint32_t i;
+
+ if (sl) {
+ if (sl->sessions) {
+ for (i = 0; i < sl->max_sessions; i++) {
+ pthread_mutex_destroy(&sl->sessions[i].session_lock);
+ }
+ free(sl->sessions);
+ }
+
+ pthread_mutex_destroy(&sl->setcallback_lock);
+ pthread_mutex_destroy(&sl->global_lock);
+
+ free(sl);
+ }
+}
+
+int en50221_sl_get_error(struct en50221_session_layer *sl)
+{
+ return sl->error;
+}
+
+void en50221_sl_register_lookup_callback(struct en50221_session_layer *sl,
+ en50221_sl_lookup_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&sl->setcallback_lock);
+ sl->lookup = callback;
+ sl->lookup_arg = arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+}
+
+void en50221_sl_register_session_callback(struct en50221_session_layer *sl,
+ en50221_sl_session_callback
+ callback, void *arg)
+{
+ pthread_mutex_lock(&sl->setcallback_lock);
+ sl->session = callback;
+ sl->session_arg = arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+}
+
+int en50221_sl_create_session(struct en50221_session_layer *sl,
+ int slot_id, uint8_t connection_id,
+ uint32_t resource_id,
+ en50221_sl_resource_callback callback,
+ void *arg)
+{
+ // lookup next free session_id:
+ pthread_mutex_lock(&sl->global_lock);
+ int session_number =
+ en50221_sl_alloc_new_session(sl, resource_id, slot_id,
+ connection_id, callback, arg);
+ if (session_number == -1) {
+ pthread_mutex_unlock(&sl->global_lock);
+ return -1;
+ }
+ pthread_mutex_unlock(&sl->global_lock);
+
+ // make up the header
+ uint8_t hdr[8];
+ hdr[0] = ST_CREATE_SESSION;
+ hdr[1] = 6;
+ hdr[2] = resource_id >> 24;
+ hdr[3] = resource_id >> 16;
+ hdr[4] = resource_id >> 8;
+ hdr[5] = resource_id;
+ hdr[6] = session_number >> 8;
+ hdr[7] = session_number;
+
+ // send this command
+ if (en50221_tl_send_data(sl->tl, slot_id, connection_id, hdr, 8)) {
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (sl->sessions[session_number].state == S_STATE_IN_CREATION) {
+ sl->sessions[session_number].state = S_STATE_IDLE;
+ }
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ sl->error = en50221_tl_get_error(sl->tl);
+ return -1;
+ }
+ // ok.
+ return session_number;
+}
+
+int en50221_sl_destroy_session(struct en50221_session_layer *sl,
+ uint16_t session_number)
+{
+ if (session_number >= sl->max_sessions) {
+ sl->error = EN50221ERR_BADSESSIONNUMBER;
+ return -1;
+ }
+
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (!(sl->sessions[session_number].state & (S_STATE_ACTIVE | S_STATE_IN_DELETION))) {
+ sl->error = EN50221ERR_BADSESSIONNUMBER;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return -1;
+ }
+ // set the state
+ sl->sessions[session_number].state = S_STATE_IN_DELETION;
+
+ // get essential details
+ uint8_t slot_id = sl->sessions[session_number].slot_id;
+ uint8_t connection_id = sl->sessions[session_number].connection_id;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // sendit
+ uint8_t hdr[4];
+ hdr[0] = ST_CLOSE_SESSION_REQ;
+ hdr[1] = 2;
+ hdr[2] = session_number >> 8;
+ hdr[3] = session_number;
+ if (en50221_tl_send_data(sl->tl, slot_id, connection_id, hdr, 4)) {
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (sl->sessions[session_number].state == S_STATE_IN_DELETION) {
+ sl->sessions[session_number].state = S_STATE_IDLE;
+ }
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ sl->error = en50221_tl_get_error(sl->tl);
+ return -1;
+ }
+
+ return 0;
+}
+
+int en50221_sl_send_data(struct en50221_session_layer *sl,
+ uint16_t session_number,
+ uint8_t *data,
+ uint16_t data_length)
+{
+ if (session_number >= sl->max_sessions) {
+ sl->error = EN50221ERR_BADSESSIONNUMBER;
+ return -1;
+ }
+
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (sl->sessions[session_number].state != S_STATE_ACTIVE) {
+ sl->error = EN50221ERR_BADSESSIONNUMBER;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return -1;
+ }
+ // get essential details
+ uint8_t slot_id = sl->sessions[session_number].slot_id;
+ uint8_t connection_id = sl->sessions[session_number].connection_id;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // sendit
+ struct iovec iov[2];
+ uint8_t hdr[4];
+ hdr[0] = ST_SESSION_NUMBER;
+ hdr[1] = 2;
+ hdr[2] = session_number >> 8;
+ hdr[3] = session_number;
+ iov[0].iov_base = hdr;
+ iov[0].iov_len = 4;
+ iov[1].iov_base = data;
+ iov[1].iov_len = data_length;
+ if (en50221_tl_send_datav(sl->tl, slot_id, connection_id, iov, 2)) {
+ sl->error = en50221_tl_get_error(sl->tl);
+ return -1;
+ }
+
+ return 0;
+}
+
+int en50221_sl_send_datav(struct en50221_session_layer *sl,
+ uint16_t session_number,
+ struct iovec *vector,
+ int iov_count)
+{
+ if (session_number >= sl->max_sessions) {
+ sl->error = EN50221ERR_BADSESSIONNUMBER;
+ return -1;
+ }
+
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (sl->sessions[session_number].state != S_STATE_ACTIVE) {
+ sl->error = EN50221ERR_BADSESSIONNUMBER;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return -1;
+ }
+ if (iov_count > 9) {
+ sl->error = EN50221ERR_IOVLIMIT;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return -1;
+ }
+ uint8_t slot_id = sl->sessions[session_number].slot_id;
+ uint8_t connection_id = sl->sessions[session_number].connection_id;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // make up the header
+ struct iovec out_iov[10];
+ uint8_t hdr[4];
+ hdr[0] = ST_SESSION_NUMBER;
+ hdr[1] = 2;
+ hdr[2] = session_number >> 8;
+ hdr[3] = session_number;
+ out_iov[0].iov_base = hdr;
+ out_iov[0].iov_len = 4;
+
+ // make up the data
+ memcpy(&out_iov[1], vector, iov_count * sizeof(struct iovec));
+
+ // send this command
+ if (en50221_tl_send_datav(sl->tl, slot_id, connection_id, out_iov, iov_count + 1)) {
+ sl->error = en50221_tl_get_error(sl->tl);
+ return -1;
+ }
+ return 0;
+}
+
+int en50221_sl_broadcast_data(struct en50221_session_layer *sl,
+ int slot_id, uint32_t resource_id,
+ uint8_t *data, uint16_t data_length)
+{
+ uint32_t i;
+
+ for (i = 0; i < sl->max_sessions; i++) {
+ pthread_mutex_lock(&sl->sessions[i].session_lock);
+
+ if (sl->sessions[i].state != S_STATE_ACTIVE) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ continue;
+ }
+ if ((slot_id != -1)
+ && (slot_id != sl->sessions[i].slot_id)) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ continue;
+ }
+
+ if (sl->sessions[i].resource_id == resource_id) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ en50221_sl_send_data(sl, i, data, data_length);
+ } else {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ }
+ }
+
+ return 0;
+}
+
+
+
+static void en50221_sl_handle_open_session_request(struct en50221_session_layer *sl,
+ uint8_t *data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // check
+ if (data_length < 5) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ if (data[0] != 4) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ // get the resource id
+ uint32_t requested_resource_id =
+ (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4];
+
+ // get lookup callback details
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_lookup_callback lcb = sl->lookup;
+ void *lcb_arg = sl->lookup_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ // first of all, lookup this resource id
+ int status = S_STATUS_CLOSE_NO_RES;
+ en50221_sl_resource_callback resource_callback = NULL;
+ void *resource_arg = NULL;
+ uint32_t connected_resource_id;
+ if (lcb) {
+ status =
+ lcb(lcb_arg, slot_id, requested_resource_id,
+ &resource_callback, &resource_arg,
+ &connected_resource_id);
+ switch (status) {
+ case 0:
+ status = S_STATUS_OPEN;
+ break;
+
+ case -1:
+ status = S_STATUS_CLOSE_NO_RES;
+ break;
+
+ case -2:
+ status = S_STATUS_CLOSE_RES_LOW_VERSION;
+ break;
+
+ case -3:
+ status = S_STATUS_CLOSE_RES_UNAVAILABLE;
+ break;
+ }
+ }
+ // if we found it, get a new session for it
+ int session_number = -1;
+ if (status == S_STATUS_OPEN) {
+ // lookup next free session_id:
+ pthread_mutex_lock(&sl->global_lock);
+ session_number =
+ en50221_sl_alloc_new_session(sl, connected_resource_id,
+ slot_id, connection_id,
+ resource_callback,
+ resource_arg);
+ pthread_mutex_unlock(&sl->global_lock);
+
+ if (session_number == -1) {
+ status = S_STATUS_CLOSE_NO_RES;
+ } else {
+ // inform upper layers/ check availability
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+ if (cb) {
+ if (cb(cb_arg, S_SCALLBACK_REASON_CAMCONNECTING,
+ slot_id, session_number,
+ connected_resource_id)) {
+ status = S_STATUS_CLOSE_RES_BUSY;
+ }
+ } else {
+ status = S_STATUS_CLOSE_RES_UNAVAILABLE;
+ }
+ }
+ }
+ // send response
+ uint8_t hdr[9];
+ hdr[0] = ST_OPEN_SESSION_RES;
+ hdr[1] = 7;
+ hdr[2] = status;
+ hdr[3] = connected_resource_id >> 24;
+ hdr[4] = connected_resource_id >> 16;
+ hdr[5] = connected_resource_id >> 8;
+ hdr[6] = connected_resource_id;
+ hdr[7] = session_number >> 8;
+ hdr[8] = session_number;
+ if (en50221_tl_send_data(sl->tl, slot_id, connection_id, hdr, 9)) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Transport layer error %i occurred\n",
+ en50221_tl_get_error(sl->tl));
+ status = S_STATUS_CLOSE_NO_RES;
+ // fallthrough
+ }
+ // inform upper layers what happened
+ if (session_number != -1) {
+ // setup session state apppropriately from upper layer response
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (status != S_STATUS_OPEN) {
+ sl->sessions[session_number].state = S_STATE_IDLE;
+ } else {
+ sl->sessions[session_number].state = S_STATE_ACTIVE;
+ }
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // tell upper layers
+ if (sl->sessions[session_number].state == S_STATE_ACTIVE) {
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ if (status == S_STATUS_OPEN) {
+ if (cb)
+ cb(cb_arg,
+ S_SCALLBACK_REASON_CAMCONNECTED,
+ slot_id, session_number,
+ connected_resource_id);
+ } else {
+ sl->sessions[session_number].state =
+ S_STATE_IDLE;
+ if (cb)
+ cb(cb_arg,
+ S_SCALLBACK_REASON_CAMCONNECTFAIL,
+ slot_id, session_number,
+ connected_resource_id);
+ }
+ }
+ }
+}
+
+static void en50221_sl_handle_close_session_request(struct en50221_session_layer *sl,
+ uint8_t * data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // check
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ if (data[0] != 2) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ // extract session number
+ uint16_t session_number = (data[1] << 8) | data[2];
+
+ // check session number is ok
+ uint8_t code = 0x00;
+ uint32_t resource_id = 0;
+ if (session_number >= sl->max_sessions) {
+ code = 0xF0; // session close error
+ print(LOG_LEVEL, ERROR, 1, "Received bad session id %i\n",
+ slot_id);
+ } else {
+ pthread_mutex_lock(&sl->sessions[session_number].
+ session_lock);
+ if (slot_id != sl->sessions[session_number].slot_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ code = 0xF0; // session close error
+ }
+ if (connection_id != sl->sessions[session_number].connection_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ code = 0xF0; // session close error
+ }
+ if (!(sl->sessions[session_number].state & (S_STATE_ACTIVE | S_STATE_IN_DELETION))) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ code = 0xF0; // session close error
+ }
+
+ if (code == 0x00) {
+ sl->sessions[session_number].state = S_STATE_IDLE;
+ code = 0x00; // close ok
+ }
+ resource_id = sl->sessions[session_number].resource_id;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ }
+
+ // make up the response
+ uint8_t hdr[5];
+ hdr[0] = ST_CLOSE_SESSION_RES;
+ hdr[1] = 3;
+ hdr[2] = code;
+ hdr[3] = session_number >> 8;
+ hdr[4] = session_number;
+
+ // sendit
+ if (en50221_tl_send_data(sl->tl, slot_id, connection_id, hdr, 5)) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Transport layer reports error %i on slot %i\n",
+ en50221_tl_get_error(sl->tl), slot_id);
+ }
+ // callback to announce destruction to resource if it was ok
+ if (code == 0x00) {
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ if (cb)
+ cb(cb_arg, S_SCALLBACK_REASON_CLOSE, slot_id,
+ session_number, resource_id);
+ }
+}
+
+static void en50221_sl_handle_create_session_response(struct en50221_session_layer *sl,
+ uint8_t * data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // check
+ if (data_length < 8) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ if (data[0] != 7) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ // extract session number
+ uint16_t session_number = (data[5] << 8) | data[6];
+
+ // check session number is ok
+ if (session_number >= sl->max_sessions) {
+ print(LOG_LEVEL, ERROR, 1, "Received bad session id %i\n",
+ slot_id);
+ return;
+ }
+
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (slot_id != sl->sessions[session_number].slot_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ if (connection_id != sl->sessions[session_number].connection_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ if (sl->sessions[session_number].state != S_STATE_IN_CREATION) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ // extract status
+ if (data[1] != S_STATUS_OPEN) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Session creation failed 0x%02x\n", data[1]);
+ sl->sessions[session_number].state = S_STATE_IDLE;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // inform upper layers
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+ if (cb)
+ cb(cb_arg, S_SCALLBACK_REASON_CONNECTFAIL, slot_id,
+ session_number,
+ sl->sessions[session_number].resource_id);
+ return;
+ }
+ // set it active
+ sl->sessions[session_number].state = S_STATE_ACTIVE;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // inform upper layers
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+ if (cb)
+ cb(cb_arg, S_SCALLBACK_REASON_CONNECTED, slot_id,
+ session_number,
+ sl->sessions[session_number].resource_id);
+}
+
+static void en50221_sl_handle_close_session_response(struct en50221_session_layer *sl,
+ uint8_t *data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // check
+ if (data_length < 5) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ if (data[0] != 4) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ return;
+ }
+ // extract session number
+ uint16_t session_number = (data[2] << 8) | data[3];
+
+ // check session number is ok
+ if (session_number >= sl->max_sessions) {
+ print(LOG_LEVEL, ERROR, 1, "Received bad session id %i\n", slot_id);
+ return;
+ }
+
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (slot_id != sl->sessions[session_number].slot_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ if (connection_id != sl->sessions[session_number].connection_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ if (sl->sessions[session_number].state != S_STATE_IN_DELETION) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ // extract status
+ if (data[1] != 0x00) {
+ print(LOG_LEVEL, ERROR, 1, "Session close failed 0x%02x\n", data[1]);
+ // just fallthrough anyway
+ }
+ // completed
+ sl->sessions[session_number].state = S_STATE_IDLE;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+}
+
+static void en50221_sl_handle_session_package(struct en50221_session_layer *sl,
+ uint8_t *data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // check
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %i\n",
+ slot_id);
+ return;
+ }
+ if (data[0] != 2) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %i\n",
+ slot_id);
+ return;
+ }
+ // get session number
+ uint16_t session_number = (data[1] << 8) | data[2];
+
+ // check it
+ if (session_number >= sl->max_sessions) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with bad session_number from module on slot %i\n",
+ slot_id);
+ return;
+ }
+
+ pthread_mutex_lock(&sl->sessions[session_number].session_lock);
+ if (slot_id != sl->sessions[session_number].slot_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ if (connection_id != sl->sessions[session_number].connection_id) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unexpected session on invalid slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+ if (sl->sessions[session_number].state != S_STATE_ACTIVE) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with bad session_number from module on slot %i\n",
+ slot_id);
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+ return;
+ }
+
+ en50221_sl_resource_callback cb = sl->sessions[session_number].callback;
+ void *cb_arg = sl->sessions[session_number].callback_arg;
+ uint32_t resource_id = sl->sessions[session_number].resource_id;
+ pthread_mutex_unlock(&sl->sessions[session_number].session_lock);
+
+ // there can be > 1 APDU following the package - all for the same session/resource_id tho.
+ data += 3;
+ data_length -= 3;
+ while (data_length) {
+ // check length field
+ if (data_length < 3) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received invalid sized session package from slot %i\n",
+ slot_id);
+ return;
+ }
+ // parse the APDU's length field
+ int length_field_len;
+ uint16_t asn_data_length;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data + 3, data_length - 3)) < 0) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received invalid sized session package from slot %i\n",
+ slot_id);
+ return;
+ }
+ uint32_t apdu_length = 3 + length_field_len + asn_data_length;
+
+ // check there is enough data
+ if (apdu_length > data_length) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received invalid sized session package from slot %i\n",
+ slot_id);
+ return;
+ }
+ // pass the APDU up to the higher layers
+ if (cb)
+ cb(cb_arg, slot_id, session_number, resource_id, data, apdu_length);
+
+ // next!
+ data += apdu_length;
+ data_length -= apdu_length;
+ }
+
+}
+
+static void en50221_sl_transport_callback(void *arg, int reason,
+ uint8_t *data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ struct en50221_session_layer *sl =
+ (struct en50221_session_layer *) arg;
+ uint32_t i;
+
+ // deal with the reason for this callback
+ switch (reason) {
+ case T_CALLBACK_REASON_DATA:
+ // fallthrough into rest of this function
+ break;
+
+ case T_CALLBACK_REASON_CONNECTIONOPEN:
+ {
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ if (cb)
+ cb(cb_arg, S_SCALLBACK_REASON_TC_CONNECT,
+ slot_id, connection_id, 0);
+ return;
+ }
+
+ case T_CALLBACK_REASON_CAMCONNECTIONOPEN:
+ {
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ if (cb)
+ cb(cb_arg,
+ S_SCALLBACK_REASON_TC_CAMCONNECT,
+ slot_id, connection_id, 0);
+ return;
+ }
+
+ case T_CALLBACK_REASON_CONNECTIONCLOSE:
+ {
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ for (i = 0; i < sl->max_sessions; i++) {
+ pthread_mutex_lock(&sl->sessions[i].session_lock);
+
+ if (sl->sessions[i].state == S_STATE_IDLE) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ continue;
+ }
+ if (sl->sessions[i].connection_id != connection_id) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ continue;
+ }
+
+ sl->sessions[i].state = S_STATE_IDLE;
+
+ uint8_t _slot_id = sl->sessions[i].slot_id;
+ uint32_t resource_id = sl->sessions[i].resource_id;
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+
+ if (cb)
+ cb(cb_arg, S_SCALLBACK_REASON_CLOSE, _slot_id, i, resource_id);
+ }
+ return;
+ }
+
+ case T_CALLBACK_REASON_SLOTCLOSE:
+ {
+ pthread_mutex_lock(&sl->setcallback_lock);
+ en50221_sl_session_callback cb = sl->session;
+ void *cb_arg = sl->session_arg;
+ pthread_mutex_unlock(&sl->setcallback_lock);
+
+ for (i = 0; i < sl->max_sessions; i++) {
+ pthread_mutex_lock(&sl->sessions[i].session_lock);
+
+ if (sl->sessions[i].state == S_STATE_IDLE) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ continue;
+ }
+ if (sl->sessions[i].slot_id != slot_id) {
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+ continue;
+ }
+ sl->sessions[i].state = S_STATE_IDLE;
+
+ uint32_t resource_id = sl->sessions[i].resource_id;
+ pthread_mutex_unlock(&sl->sessions[i].session_lock);
+
+ if (cb)
+ cb(cb_arg, S_SCALLBACK_REASON_CLOSE, slot_id, i, resource_id);
+
+ }
+ return;
+ }
+ }
+
+ // sanity check data length
+ if (data_length < 1) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %i\n",
+ slot_id);
+ return;
+ }
+ // deal with the data
+ uint8_t spdu_tag = data[0];
+ switch (spdu_tag) {
+ case ST_OPEN_SESSION_REQ:
+ en50221_sl_handle_open_session_request(sl, data + 1,
+ data_length - 1,
+ slot_id,
+ connection_id);
+ break;
+
+ case ST_CLOSE_SESSION_REQ:
+ en50221_sl_handle_close_session_request(sl, data + 1,
+ data_length - 1,
+ slot_id,
+ connection_id);
+ break;
+
+ case ST_SESSION_NUMBER:
+ en50221_sl_handle_session_package(sl, data + 1,
+ data_length - 1, slot_id,
+ connection_id);
+ break;
+
+ case ST_CREATE_SESSION_RES:
+ en50221_sl_handle_create_session_response(sl, data + 1,
+ data_length - 1,
+ slot_id,
+ connection_id);
+ break;
+
+ case ST_CLOSE_SESSION_RES:
+ en50221_sl_handle_close_session_response(sl, data + 1,
+ data_length - 1,
+ slot_id,
+ connection_id);
+ break;
+
+ default:
+ print(LOG_LEVEL, ERROR, 1,
+ "Received unknown session tag %02x from module on slot %i",
+ spdu_tag, slot_id);
+ break;
+ }
+}
+
+static int en50221_sl_alloc_new_session(struct en50221_session_layer *sl,
+ uint32_t resource_id,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ en50221_sl_resource_callback
+ callback, void *arg)
+{
+ int session_number = -1;
+ uint32_t i;
+ for (i = 1; i < sl->max_sessions; i++) {
+ if (sl->sessions[i].state == S_STATE_IDLE) {
+ session_number = i;
+ break;
+ }
+ }
+ if (session_number == -1) {
+ sl->error = EN50221ERR_OUTOFSESSIONS;
+ return -1;
+ }
+ // setup the session
+ sl->sessions[session_number].state = S_STATE_IN_CREATION;
+ sl->sessions[session_number].resource_id = resource_id;
+ sl->sessions[session_number].slot_id = slot_id;
+ sl->sessions[session_number].connection_id = connection_id;
+ sl->sessions[session_number].callback = callback;
+ sl->sessions[session_number].callback_arg = arg;
+
+ // ok
+ return session_number;
+}
diff --git a/lib/libdvben50221/en50221_session.h b/lib/libdvben50221/en50221_session.h
new file mode 100644
index 0000000..7b33518
--- /dev/null
+++ b/lib/libdvben50221/en50221_session.h
@@ -0,0 +1,232 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 session layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian@jusst.de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef __EN50221_SESSION_H__
+#define __EN50221_SESSION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <libdvben50221/en50221_transport.h>
+
+#define S_SCALLBACK_REASON_CAMCONNECTING 0x00 // CAM originated session connecting to resource (check for availability)
+#define S_SCALLBACK_REASON_CAMCONNECTED 0x01 // CAM originated session connection established succesfully
+#define S_SCALLBACK_REASON_CAMCONNECTFAIL 0x02 // CAM originated session connection failed
+#define S_SCALLBACK_REASON_CONNECTED 0x03 // Host originated session ACKed by CAM.
+#define S_SCALLBACK_REASON_CONNECTFAIL 0x04 // Host originated session NACKed by CAM.
+#define S_SCALLBACK_REASON_CLOSE 0x05 // Session closed
+#define S_SCALLBACK_REASON_TC_CONNECT 0x06 // A host originated transport connection has been established.
+#define S_SCALLBACK_REASON_TC_CAMCONNECT 0x07 // A CAM originated transport connection has been established.
+
+
+/**
+ * Opaque type representing a session layer.
+ */
+struct en50221_session_layer;
+
+/**
+ * Type definition for resource callback function - called by session layer when data
+ * arrives for a particular resource.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number.
+ * @param resource_id Resource id.
+ * @param data The data.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, or -1 on failure.
+ */
+typedef int (*en50221_sl_resource_callback) (void *arg,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id,
+ uint8_t * data,
+ uint32_t data_length);
+
+/**
+ * Type definition for resource lookup callback function - used by the session layer to
+ * look up requested resources.
+ *
+ * @param arg Private argument.
+ * @param slot_id Slot id the request came from.
+ * @param requested_resource_id Resource id requested.
+ * @param callback_out Output parameter for pointer to resource callback function.
+ * @param arg_out Output parameter for arg to pass to resource callback.
+ * @param resource_id_out Set this to the resource_id connected to (e.g. may differ from resource_id due to versions).
+ * @return 0 on success,
+ * -1 if the resource was not found,
+ * -2 if it exists, but had a lower version, or
+ * -3 if it exists, but was unavailable.
+ */
+typedef int (*en50221_sl_lookup_callback) (void *arg,
+ uint8_t slot_id,
+ uint32_t requested_resource_id,
+ en50221_sl_resource_callback * callback_out,
+ void **arg_out,
+ uint32_t *resource_id_out);
+
+
+/**
+ * Type definition for session callback function - used to inform top level code when a CAM
+ * modifies a session to a resource.
+ *
+ * @param arg Private argument.
+ * @param reason One of the S_CCALLBACK_REASON_* values above.
+ * @param slot_id Slot id concerned.
+ * @param session_number Session number.
+ * @param resource_id Resource id.
+ * @return 0 on sucess, or -1 on error.
+ */
+typedef int (*en50221_sl_session_callback) (void *arg, int reason,
+ uint8_t slot_id,
+ uint16_t session_number,
+ uint32_t resource_id);
+
+/**
+ * Construct a new instance of the session layer.
+ *
+ * @param tl The en50221_transport_layer instance to use.
+ * @param max_sessions Maximum number of sessions supported.
+ * @return The en50221_session_layer instance, or NULL on error.
+ */
+extern struct en50221_session_layer *en50221_sl_create(struct en50221_transport_layer *tl,
+ uint32_t max_sessions);
+
+/**
+ * Destroy an instance of the session layer.
+ *
+ * @param tl The en50221_session_layer instance.
+ */
+extern void en50221_sl_destroy(struct en50221_session_layer *sl);
+
+/**
+ * Gets the last error.
+ *
+ * @param tl The en50221_session_layer instance.
+ * @return One of the EN50221ERR_* values.
+ */
+extern int en50221_sl_get_error(struct en50221_session_layer *tl);
+
+/**
+ * Register the callback for resource lookup.
+ *
+ * @param sl The en50221_session_layer instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_sl_register_lookup_callback(struct en50221_session_layer *sl,
+ en50221_sl_lookup_callback callback,
+ void *arg);
+
+/**
+ * Register the callback for informing about session from a cam.
+ *
+ * @param sl The en50221_session_layer instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_sl_register_session_callback(struct en50221_session_layer *sl,
+ en50221_sl_session_callback callback,
+ void *arg);
+
+/**
+ * Create a new session to a module in a slot.
+ *
+ * @param sl The en50221_session_layer instance.
+ * @param slot The slot to connect to.
+ * @param resource_id The resource_id to connect to.
+ * @param callback The callback for received data.
+ * @param arg Argument to pass to the callback.
+ * @return The new session_number, or -1 on error.
+ */
+extern int en50221_sl_create_session(struct en50221_session_layer *sl, int slot_id,
+ uint8_t connection_id,
+ uint32_t resource_id,
+ en50221_sl_resource_callback callback,
+ void *arg);
+
+/**
+ * Destroy a session.
+ *
+ * @param sl The en50221_session_layer instance.
+ * @param session_number The session to destroy.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_sl_destroy_session(struct en50221_session_layer *sl,
+ uint16_t session_number);
+
+/**
+ * this function is used to take a data-block, pack into
+ * into a SPDU (SESSION_NUMBER) and send it to the transport layer
+ *
+ * @param sl The en50221_session_layer instance to use.
+ * @param session_number Session number concerned.
+ * @param data Data to send.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_sl_send_data(struct en50221_session_layer *sl,
+ uint16_t session_number,
+ uint8_t * data,
+ uint16_t data_length);
+
+/**
+ * this function is used to take a data-block, pack into
+ * into a SPDU (SESSION_NUMBER) and send it to the transport layer
+ *
+ * @param sl The en50221_session_layer instance to use.
+ * @param session_number Session number concerned.
+ * @param vector IOVEC to send.
+ * @param iov_count Number of elements in io vector.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_sl_send_datav(struct en50221_session_layer *sl,
+ uint16_t session_number,
+ struct iovec *vector,
+ int iov_count);
+
+/**
+ * this is used to send a message to all sessions, linked
+ * to resource res
+ *
+ * @param tl The en50221_session_layer instance to use.
+ * @param slot_id Set to -1 to send to any slot. Other values will send to only that slot.
+ * @param resource_id Resource id concerned.
+ * @param data Data to send.
+ * @param data_length Length of data in bytes.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_sl_broadcast_data(struct en50221_session_layer *sl,
+ int slot_id,
+ uint32_t resource_id,
+ uint8_t * data,
+ uint16_t data_length);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvben50221/en50221_stdcam.c b/lib/libdvben50221/en50221_stdcam.c
new file mode 100644
index 0000000..a00a844
--- /dev/null
+++ b/lib/libdvben50221/en50221_stdcam.c
@@ -0,0 +1,54 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <libdvbapi/dvbca.h>
+#include "en50221_stdcam.h"
+
+struct en50221_stdcam *en50221_stdcam_create(int adapter, int slotnum,
+ struct en50221_transport_layer *tl,
+ struct en50221_session_layer *sl)
+{
+ struct en50221_stdcam *result = NULL;
+
+ int cafd = dvbca_open(adapter, 0);
+ if (cafd == -1)
+ return NULL;
+
+ int ca_type = dvbca_get_interface_type(cafd, slotnum);
+ switch(ca_type) {
+ case DVBCA_INTERFACE_LINK:
+ result = en50221_stdcam_llci_create(cafd, slotnum, tl, sl);
+ break;
+
+ case DVBCA_INTERFACE_HLCI:
+ result = en50221_stdcam_hlci_create(cafd, slotnum);
+ break;
+ }
+
+ if (result == NULL)
+ close(cafd);
+ return result;
+}
diff --git a/lib/libdvben50221/en50221_stdcam.h b/lib/libdvben50221/en50221_stdcam.h
new file mode 100644
index 0000000..154ff76
--- /dev/null
+++ b/lib/libdvben50221/en50221_stdcam.h
@@ -0,0 +1,102 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef EN50221_STDCAM_H
+#define EN50221_STDCAM_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libdvben50221/en50221_app_ai.h>
+#include <libdvben50221/en50221_app_ca.h>
+#include <libdvben50221/en50221_app_mmi.h>
+#include <libdvben50221/en50221_session.h>
+#include <libdvben50221/en50221_transport.h>
+
+enum en50221_stdcam_status {
+ EN50221_STDCAM_CAM_NONE,
+ EN50221_STDCAM_CAM_INRESET,
+ EN50221_STDCAM_CAM_OK,
+ EN50221_STDCAM_CAM_BAD,
+};
+
+struct en50221_stdcam {
+ /* one of more of the following may be NULL if a CAM does not support it */
+ struct en50221_app_ai *ai_resource;
+ struct en50221_app_ca *ca_resource;
+ struct en50221_app_mmi *mmi_resource;
+
+ /* if any of these are -1, no connection is in place to this resource yet */
+ int ai_session_number;
+ int ca_session_number;
+ int mmi_session_number;
+
+ /* poll the stdcam instance */
+ enum en50221_stdcam_status (*poll)(struct en50221_stdcam *stdcam);
+
+ /* inform the stdcam of the current DVB time */
+ void (*dvbtime)(struct en50221_stdcam *stdcam, time_t dvbtime);
+
+ /* destroy the stdcam instance */
+ void (*destroy)(struct en50221_stdcam *stdcam, int closefd);
+};
+
+/**
+ * Create an instance of the STDCAM for an LLCI interface.
+ *
+ * @param cafd FD of the CA device.
+ * @param slotnum Slotnum on that CA device.
+ * @param tl Transport layer instance to use.
+ * @param sl Session layer instance to use.
+ * @return en50221_stdcam instance, or NULL on error.
+ */
+extern struct en50221_stdcam *en50221_stdcam_llci_create(int cafd, int slotnum,
+ struct en50221_transport_layer *tl,
+ struct en50221_session_layer *sl);
+
+/**
+ * Create an instance of the STDCAM for an HLCI interface.
+ *
+ * @param cafd FD of the CA device.
+ * @param slotnum Slotnum on that CA device.
+ * @return en50221_stdcam instance, or NULL on error.
+ */
+extern struct en50221_stdcam *en50221_stdcam_hlci_create(int cafd, int slotnum);
+
+/**
+ * Convenience method to create a STDCAM interface for a ca device on a particular adapter.
+ *
+ * @param adapter The DVB adapter concerned.
+ * @param slotnum The ca slot number on that adapter.
+ * @param tl Transport layer instance to use (unused for HLCI cams).
+ * @param sl Session layer instance to use (unused for HLCI cams).
+ * @return en50221_stdcam instance, or NULL on error.
+ */
+extern struct en50221_stdcam *en50221_stdcam_create(int adapter, int slotnum,
+ struct en50221_transport_layer *tl,
+ struct en50221_session_layer *sl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libdvben50221/en50221_stdcam_hlci.c b/lib/libdvben50221/en50221_stdcam_hlci.c
new file mode 100644
index 0000000..f21637b
--- /dev/null
+++ b/lib/libdvben50221/en50221_stdcam_hlci.c
@@ -0,0 +1,216 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <libdvbapi/dvbca.h>
+#include "en50221_app_utils.h"
+#include "en50221_app_tags.h"
+#include "en50221_stdcam.h"
+
+
+struct en50221_stdcam_hlci {
+ struct en50221_stdcam stdcam;
+
+ int cafd;
+ int slotnum;
+ int initialised;
+ struct en50221_app_send_functions sendfuncs;
+};
+
+static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd);
+static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam);
+static int hlci_cam_added(struct en50221_stdcam_hlci *hlci);
+static int hlci_send_data(void *arg, uint16_t session_number,
+ uint8_t * data, uint16_t data_length);
+static int hlci_send_datav(void *arg, uint16_t session_number,
+ struct iovec *vector, int iov_count);
+
+
+
+
+struct en50221_stdcam *en50221_stdcam_hlci_create(int cafd, int slotnum)
+{
+ // try and allocate space for the HLCI stdcam
+ struct en50221_stdcam_hlci *hlci =
+ malloc(sizeof(struct en50221_stdcam_hlci));
+ if (hlci == NULL) {
+ return NULL;
+ }
+ memset(hlci, 0, sizeof(struct en50221_stdcam_hlci));
+
+ // create the sendfuncs
+ hlci->sendfuncs.arg = hlci;
+ hlci->sendfuncs.send_data = hlci_send_data;
+ hlci->sendfuncs.send_datav = hlci_send_datav;
+
+ // create the resources (NOTE: we just use fake session numbers here)
+ hlci->stdcam.ai_resource = en50221_app_ai_create(&hlci->sendfuncs);
+ hlci->stdcam.ai_session_number = 0;
+ hlci->stdcam.ca_resource = en50221_app_ca_create(&hlci->sendfuncs);
+ hlci->stdcam.ca_session_number = 1;
+// hlci->stdcam.mmi_resource = en50221_app_mmi_create(&hlci->sendfuncs);
+ hlci->stdcam.mmi_session_number = -1;
+
+ // done
+ hlci->stdcam.destroy = en50221_stdcam_hlci_destroy;
+ hlci->stdcam.poll = en50221_stdcam_hlci_poll;
+ hlci->slotnum = slotnum;
+ hlci->cafd = cafd;
+ return &hlci->stdcam;
+}
+
+static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd)
+{
+ struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;
+
+ if (hlci->stdcam.ai_resource)
+ en50221_app_ai_destroy(hlci->stdcam.ai_resource);
+ if (hlci->stdcam.ca_resource)
+ en50221_app_ca_destroy(hlci->stdcam.ca_resource);
+ if (hlci->stdcam.mmi_resource)
+ en50221_app_mmi_destroy(hlci->stdcam.mmi_resource);
+
+ if (closefd)
+ close(hlci->cafd);
+
+ free(hlci);
+}
+
+static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam)
+{
+ struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;
+
+ switch(dvbca_get_cam_state(hlci->cafd, hlci->slotnum)) {
+ case DVBCA_CAMSTATE_MISSING:
+ hlci->initialised = 0;
+ break;
+
+ case DVBCA_CAMSTATE_READY:
+ case DVBCA_CAMSTATE_INITIALISING:
+ if (!hlci->initialised)
+ hlci_cam_added(hlci);
+ break;
+ }
+
+ // delay to prevent busy loop
+ usleep(10);
+
+ if (!hlci->initialised) {
+ return EN50221_STDCAM_CAM_NONE;
+ }
+ return EN50221_STDCAM_CAM_OK;
+}
+
+
+
+static int hlci_cam_added(struct en50221_stdcam_hlci *hlci)
+{
+ uint8_t buf[256];
+ int size;
+
+ // get application information
+ if (en50221_app_ai_enquiry(hlci->stdcam.ai_resource, 0)) {
+ return -EIO;
+ }
+ if ((size = dvbca_hlci_read(hlci->cafd, TAG_APP_INFO, buf, sizeof(buf))) < 0) {
+ return size;
+ }
+ if (en50221_app_ai_message(hlci->stdcam.ai_resource, 0, 0, EN50221_APP_AI_RESOURCEID, buf, size)) {
+ return -EIO;
+ }
+
+ // we forge a fake CA_INFO here so the main app works - since it will expect a CA_INFO
+ // this will be replaced with a proper call (below) when the driver support is there
+ buf[0] = TAG_CA_INFO >> 16;
+ buf[1] = (uint8_t) (TAG_CA_INFO >> 8);
+ buf[2] = (uint8_t) TAG_CA_INFO;
+ buf[3] = 0;
+ if (en50221_app_ca_message(hlci->stdcam.ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, 4)) {
+ return -EIO;
+ }
+
+ /*
+ // get CA information
+ if (en50221_app_ca_info_enq(ca_resource, 0)) {
+ fprintf(stderr, "Failed to send CA INFO enquiry\n");
+ cafd = -1;
+ return -1;
+ }
+ if ((size = dvbca_hlci_read(cafd, TAG_CA_INFO, buf, sizeof(buf))) < 0) {
+ fprintf(stderr, "Failed to read CA INFO\n");
+ cafd = -1;
+ return -1;
+ }
+ if (en50221_app_ca_message(ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, size)) {
+ fprintf(stderr, "Failed to parse CA INFO\n");
+ cafd = -1;
+ return -1;
+ }
+ */
+
+ // done
+ hlci->initialised = 1;
+ return 0;
+}
+
+static int hlci_send_data(void *arg, uint16_t session_number,
+ uint8_t * data, uint16_t data_length)
+{
+ (void) session_number;
+ struct en50221_stdcam_hlci *hlci = arg;
+
+ return dvbca_hlci_write(hlci->cafd, data, data_length);
+}
+
+static int hlci_send_datav(void *arg, uint16_t session_number,
+ struct iovec *vector, int iov_count)
+{
+ (void) session_number;
+ struct en50221_stdcam_hlci *hlci = arg;
+
+ // calculate the total length of the data to send
+ uint32_t data_size = 0;
+ int i;
+ for (i = 0; i < iov_count; i++) {
+ data_size += vector[i].iov_len;
+ }
+
+ // allocate memory for it
+ uint8_t *buf = malloc(data_size);
+ if (buf == NULL) {
+ return -1;
+ }
+ // merge the iovecs
+ uint32_t pos = 0;
+ for (i = 0; i < iov_count; i++) {
+ memcpy(buf + pos, vector[i].iov_base, vector[i].iov_len);
+ pos += vector[i].iov_len;
+ }
+
+ // sendit and cleanup
+ int status = dvbca_hlci_write(hlci->cafd, buf, data_size);
+ free(buf);
+ return status;
+}
diff --git a/lib/libdvben50221/en50221_stdcam_llci.c b/lib/libdvben50221/en50221_stdcam_llci.c
new file mode 100644
index 0000000..2266bbf
--- /dev/null
+++ b/lib/libdvben50221/en50221_stdcam_llci.c
@@ -0,0 +1,437 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <libdvbapi/dvbca.h>
+#include <libdvbmisc/dvbmisc.h>
+#include "en50221_app_rm.h"
+#include "en50221_app_datetime.h"
+#include "en50221_app_utils.h"
+#include "en50221_app_tags.h"
+#include "en50221_stdcam.h"
+
+#define LLCI_RESPONSE_TIMEOUT_MS 1000
+#define LLCI_POLL_DELAY_MS 100
+
+/* resource IDs we support */
+static uint32_t resource_ids[] =
+{ EN50221_APP_RM_RESOURCEID,
+ EN50221_APP_CA_RESOURCEID,
+ EN50221_APP_AI_RESOURCEID,
+ EN50221_APP_MMI_RESOURCEID,
+ EN50221_APP_DATETIME_RESOURCEID,
+};
+#define RESOURCE_IDS_COUNT sizeof(resource_ids)/4
+
+struct llci_resource {
+ struct en50221_app_public_resource_id resid;
+ uint32_t binary_resource_id;
+ en50221_sl_resource_callback callback;
+ void *arg;
+};
+
+struct en50221_stdcam_llci {
+ struct en50221_stdcam stdcam;
+
+ int cafd;
+ int slotnum;
+ int state;
+
+ struct llci_resource resources[RESOURCE_IDS_COUNT];
+
+ struct en50221_transport_layer *tl;
+ struct en50221_session_layer *sl;
+ struct en50221_app_send_functions sendfuncs;
+ int tl_slot_id;
+
+ struct en50221_app_rm *rm_resource;
+
+ struct en50221_app_datetime *datetime_resource;
+ int datetime_session_number;
+ uint8_t datetime_response_interval;
+ time_t datetime_next_send;
+ time_t datetime_dvbtime;
+};
+
+static enum en50221_stdcam_status en50221_stdcam_llci_poll(struct en50221_stdcam *stdcam);
+static void en50221_stdcam_llci_dvbtime(struct en50221_stdcam *stdcam, time_t dvbtime);
+static void en50221_stdcam_llci_destroy(struct en50221_stdcam *stdcam, int closefd);
+static void llci_cam_added(struct en50221_stdcam_llci *llci);
+static void llci_cam_in_reset(struct en50221_stdcam_llci *llci);
+static void llci_cam_removed(struct en50221_stdcam_llci *llci);
+
+
+static int llci_lookup_callback(void *arg, uint8_t _slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out,
+ uint32_t *connected_resource_id);
+static int llci_session_callback(void *arg, int reason, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id);
+static int llci_rm_enq_callback(void *arg, uint8_t _slot_id, uint16_t session_number);
+static int llci_rm_reply_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *_resource_ids);
+static int llci_rm_changed_callback(void *arg, uint8_t _slot_id, uint16_t session_number);
+
+static int llci_datetime_enquiry_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint8_t response_interval);
+
+
+struct en50221_stdcam *en50221_stdcam_llci_create(int cafd, int slotnum,
+ struct en50221_transport_layer *tl,
+ struct en50221_session_layer *sl)
+{
+ // try and allocate space for the LLCI stdcam
+ struct en50221_stdcam_llci *llci =
+ malloc(sizeof(struct en50221_stdcam_llci));
+ if (llci == NULL) {
+ return NULL;
+ }
+ memset(llci, 0, sizeof(struct en50221_stdcam_llci));
+
+ // create the sendfuncs
+ llci->sendfuncs.arg = sl;
+ llci->sendfuncs.send_data = (en50221_send_data) en50221_sl_send_data;
+ llci->sendfuncs.send_datav = (en50221_send_datav) en50221_sl_send_datav;
+
+ // create the resource manager resource
+ int resource_idx = 0;
+ llci->rm_resource = en50221_app_rm_create(&llci->sendfuncs);
+ en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_RM_RESOURCEID);
+ llci->resources[resource_idx].binary_resource_id = EN50221_APP_RM_RESOURCEID;
+ llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_rm_message;
+ llci->resources[resource_idx].arg = llci->rm_resource;
+ en50221_app_rm_register_enq_callback(llci->rm_resource, llci_rm_enq_callback, llci);
+ en50221_app_rm_register_reply_callback(llci->rm_resource, llci_rm_reply_callback, llci);
+ en50221_app_rm_register_changed_callback(llci->rm_resource, llci_rm_changed_callback, llci);
+ resource_idx++;
+
+ // create the datetime resource
+ llci->datetime_resource = en50221_app_datetime_create(&llci->sendfuncs);
+ en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_DATETIME_RESOURCEID);
+ llci->resources[resource_idx].binary_resource_id = EN50221_APP_DATETIME_RESOURCEID;
+ llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_datetime_message;
+ llci->resources[resource_idx].arg = llci->datetime_resource;
+ en50221_app_datetime_register_enquiry_callback(llci->datetime_resource, llci_datetime_enquiry_callback, llci);
+ resource_idx++;
+ llci->datetime_session_number = -1;
+ llci->datetime_response_interval = 0;
+ llci->datetime_next_send = 0;
+ llci->datetime_dvbtime = 0;
+
+ // create the application information resource
+ llci->stdcam.ai_resource = en50221_app_ai_create(&llci->sendfuncs);
+ en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_AI_RESOURCEID);
+ llci->resources[resource_idx].binary_resource_id = EN50221_APP_AI_RESOURCEID;
+ llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_ai_message;
+ llci->resources[resource_idx].arg = llci->stdcam.ai_resource;
+ llci->stdcam.ai_session_number = -1;
+ resource_idx++;
+
+ // create the CA resource
+ llci->stdcam.ca_resource = en50221_app_ca_create(&llci->sendfuncs);
+ en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_CA_RESOURCEID);
+ llci->resources[resource_idx].binary_resource_id = EN50221_APP_CA_RESOURCEID;
+ llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_ca_message;
+ llci->resources[resource_idx].arg = llci->stdcam.ca_resource;
+ llci->stdcam.ca_session_number = -1;
+ resource_idx++;
+
+ // create the MMI resource
+ llci->stdcam.mmi_resource = en50221_app_mmi_create(&llci->sendfuncs);
+ en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_MMI_RESOURCEID);
+ llci->resources[resource_idx].binary_resource_id = EN50221_APP_MMI_RESOURCEID;
+ llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_mmi_message;
+ llci->resources[resource_idx].arg = llci->stdcam.mmi_resource;
+ llci->stdcam.mmi_session_number = -1;
+ resource_idx++;
+
+ // register session layer callbacks
+ en50221_sl_register_lookup_callback(sl, llci_lookup_callback, llci);
+ en50221_sl_register_session_callback(sl, llci_session_callback, llci);
+
+ // done
+ llci->stdcam.destroy = en50221_stdcam_llci_destroy;
+ llci->stdcam.poll = en50221_stdcam_llci_poll;
+ llci->stdcam.dvbtime = en50221_stdcam_llci_dvbtime;
+ llci->cafd = cafd;
+ llci->slotnum = slotnum;
+ llci->tl = tl;
+ llci->sl = sl;
+ llci->tl_slot_id = -1;
+ llci->state = EN50221_STDCAM_CAM_NONE;
+ return &llci->stdcam;
+}
+
+static void en50221_stdcam_llci_dvbtime(struct en50221_stdcam *stdcam, time_t dvbtime)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) stdcam;
+
+ llci->datetime_dvbtime = dvbtime;
+}
+
+static void en50221_stdcam_llci_destroy(struct en50221_stdcam *stdcam, int closefd)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) stdcam;
+
+ // "remove" the cam
+ llci_cam_removed(llci);
+
+ // destroy resources
+ if (llci->rm_resource)
+ en50221_app_rm_destroy(llci->rm_resource);
+ if (llci->datetime_resource)
+ en50221_app_datetime_destroy(llci->datetime_resource);
+ if (llci->stdcam.ai_resource)
+ en50221_app_ai_destroy(llci->stdcam.ai_resource);
+ if (llci->stdcam.ca_resource)
+ en50221_app_ca_destroy(llci->stdcam.ca_resource);
+ if (llci->stdcam.mmi_resource)
+ en50221_app_mmi_destroy(llci->stdcam.mmi_resource);
+
+ if (closefd)
+ close(llci->cafd);
+
+ free(llci);
+}
+
+
+
+
+static enum en50221_stdcam_status en50221_stdcam_llci_poll(struct en50221_stdcam *stdcam)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) stdcam;
+
+ switch(dvbca_get_cam_state(llci->cafd, llci->slotnum)) {
+ case DVBCA_CAMSTATE_MISSING:
+ if (llci->state != EN50221_STDCAM_CAM_NONE)
+ llci_cam_removed(llci);
+ break;
+
+ case DVBCA_CAMSTATE_READY:
+ if (llci->state == EN50221_STDCAM_CAM_NONE)
+ llci_cam_added(llci);
+ else if (llci->state == EN50221_STDCAM_CAM_INRESET)
+ llci_cam_in_reset(llci);
+ break;
+ }
+
+ // poll the stack
+ int error;
+ if ((error = en50221_tl_poll(llci->tl)) != 0) {
+ print(LOG_LEVEL, ERROR, 1, "Error reported by stack:%i\n", en50221_tl_get_error(llci->tl));
+ }
+
+ // send date/time response
+ if (llci->datetime_session_number != -1) {
+ time_t cur_time = time(NULL);
+ if (llci->datetime_response_interval && (cur_time > llci->datetime_next_send)) {
+ en50221_app_datetime_send(llci->datetime_resource,
+ llci->datetime_session_number,
+ llci->datetime_dvbtime, 0);
+ llci->datetime_next_send = cur_time + llci->datetime_response_interval;
+ }
+ }
+
+ return llci->state;
+}
+
+static void llci_cam_added(struct en50221_stdcam_llci *llci)
+{
+ // clear down any old structures
+ if (llci->tl_slot_id != -1) {
+ llci_cam_removed(llci);
+ }
+
+ // reset the CAM
+ dvbca_reset(llci->cafd, llci->slotnum);
+ llci->state = EN50221_STDCAM_CAM_INRESET;
+}
+
+static void llci_cam_in_reset(struct en50221_stdcam_llci *llci)
+{
+ if (dvbca_get_cam_state(llci->cafd, llci->slotnum) != DVBCA_CAMSTATE_READY) {
+ return;
+ }
+
+ // register the slot
+ if ((llci->tl_slot_id = en50221_tl_register_slot(llci->tl, llci->cafd, llci->slotnum,
+ LLCI_RESPONSE_TIMEOUT_MS, LLCI_POLL_DELAY_MS)) < 0) {
+ llci->state = EN50221_STDCAM_CAM_BAD;
+ return;
+ }
+
+ // create a new connection on the slot
+ if (en50221_tl_new_tc(llci->tl, llci->tl_slot_id) < 0) {
+ llci->state = EN50221_STDCAM_CAM_BAD;
+ llci->tl_slot_id = -1;
+ en50221_tl_destroy_slot(llci->tl, llci->tl_slot_id);
+ return;
+ }
+
+ llci->state = EN50221_STDCAM_CAM_OK;
+}
+
+static void llci_cam_removed(struct en50221_stdcam_llci *llci)
+{
+ if (llci->tl_slot_id != -1) {
+ en50221_tl_destroy_slot(llci->tl, llci->tl_slot_id);
+ llci->tl_slot_id = -1;
+ llci->datetime_session_number = -1;
+ llci->stdcam.ai_session_number = -1;
+ llci->stdcam.ca_session_number = -1;
+ llci->stdcam.mmi_session_number = -1;
+ }
+ llci->state = EN50221_STDCAM_CAM_NONE;
+}
+
+
+
+static int llci_lookup_callback(void *arg, uint8_t _slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out,
+ uint32_t *connected_resource_id)
+{
+ struct en50221_app_public_resource_id resid;
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
+ (void) _slot_id;
+
+ // decode the resource id
+ if (!en50221_app_decode_public_resource_id(&resid, requested_resource_id)) {
+ return -1;
+ }
+
+ // try and find an instance of the resource
+ uint32_t i;
+ for(i=0; i<RESOURCE_IDS_COUNT; i++) {
+ if ((resid.resource_class == llci->resources[i].resid.resource_class) &&
+ (resid.resource_type == llci->resources[i].resid.resource_type)) {
+
+ // limit sessions to certain resources
+ switch(requested_resource_id) {
+ case EN50221_APP_DATETIME_RESOURCEID:
+ if (llci->datetime_session_number != -1)
+ return -3;
+ break;
+ case EN50221_APP_AI_RESOURCEID:
+ if (llci->stdcam.ai_session_number != -1)
+ return -3;
+ break;
+ case EN50221_APP_CA_RESOURCEID:
+ if (llci->stdcam.ca_session_number != -1)
+ return -3;
+ break;
+ case EN50221_APP_MMI_RESOURCEID:
+ if (llci->stdcam.mmi_session_number != -1)
+ return -3;
+ break;
+ }
+
+ // resource is ok.
+ *callback_out = llci->resources[i].callback;
+ *arg_out = llci->resources[i].arg;
+ *connected_resource_id = llci->resources[i].binary_resource_id;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int llci_session_callback(void *arg, int reason, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
+ (void) _slot_id;
+
+ switch(reason) {
+ case S_SCALLBACK_REASON_CAMCONNECTED:
+ if (resource_id == EN50221_APP_RM_RESOURCEID) {
+ en50221_app_rm_enq(llci->rm_resource, session_number);
+ } else if (resource_id == EN50221_APP_DATETIME_RESOURCEID) {
+ llci->datetime_session_number = session_number;
+ } else if (resource_id == EN50221_APP_AI_RESOURCEID) {
+ en50221_app_ai_enquiry(llci->stdcam.ai_resource, session_number);
+ llci->stdcam.ai_session_number = session_number;
+ } else if (resource_id == EN50221_APP_CA_RESOURCEID) {
+ en50221_app_ca_info_enq(llci->stdcam.ca_resource, session_number);
+ llci->stdcam.ca_session_number = session_number;
+ } else if (resource_id == EN50221_APP_MMI_RESOURCEID) {
+ llci->stdcam.mmi_session_number = session_number;
+ }
+
+ break;
+ case S_SCALLBACK_REASON_CLOSE:
+ if (resource_id == EN50221_APP_MMI_RESOURCEID) {
+ llci->stdcam.mmi_session_number = -1;
+ }
+
+ break;
+ }
+ return 0;
+}
+
+static int llci_rm_enq_callback(void *arg, uint8_t _slot_id, uint16_t session_number)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
+ (void) _slot_id;
+
+ if (en50221_app_rm_reply(llci->rm_resource, session_number, RESOURCE_IDS_COUNT, resource_ids)) {
+ print(LOG_LEVEL, ERROR, 1, "Failed to send RM ENQ on slot %02x\n", _slot_id);
+ }
+ return 0;
+}
+
+static int llci_rm_reply_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *_resource_ids)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
+ (void) _slot_id;
+ (void) resource_id_count;
+ (void) _resource_ids;
+
+ if (en50221_app_rm_changed(llci->rm_resource, session_number)) {
+ print(LOG_LEVEL, ERROR, 1, "Failed to send RM REPLY on slot %02x\n", _slot_id);
+ }
+ return 0;
+}
+
+static int llci_rm_changed_callback(void *arg, uint8_t _slot_id, uint16_t session_number)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
+ (void) _slot_id;
+
+ if (en50221_app_rm_enq(llci->rm_resource, session_number)) {
+ print(LOG_LEVEL, ERROR, 1, "Failed to send RM CHANGED on slot %02x\n", _slot_id);
+ }
+ return 0;
+}
+
+static int llci_datetime_enquiry_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint8_t response_interval)
+{
+ struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
+ (void) _slot_id;
+
+ llci->datetime_response_interval = response_interval;
+ llci->datetime_next_send = 0;
+ if (response_interval) {
+ llci->datetime_next_send = time(NULL) + response_interval;
+ }
+ en50221_app_datetime_send(llci->datetime_resource, session_number, llci->datetime_dvbtime, 0);
+
+ return 0;
+}
diff --git a/lib/libdvben50221/en50221_transport.c b/lib/libdvben50221/en50221_transport.c
new file mode 100644
index 0000000..f6f46db
--- /dev/null
+++ b/lib/libdvben50221/en50221_transport.c
@@ -0,0 +1,1296 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <time.h>
+#include <libdvbmisc/dvbmisc.h>
+#include <libdvbapi/dvbca.h>
+#include "en50221_errno.h"
+#include "en50221_transport.h"
+#include "asn_1.h"
+
+// these are the Transport Tags, like
+// described in EN50221, Annex A.4.1.13 (pg70)
+#define T_SB 0x80 // sb primitive h<--m
+#define T_RCV 0x81 // receive primitive h-->m
+#define T_CREATE_T_C 0x82 // create transport connection primitive h-->m
+#define T_C_T_C_REPLY 0x83 // ctc reply primitive h<--m
+#define T_DELETE_T_C 0x84 // delete tc primitive h<->m
+#define T_D_T_C_REPLY 0x85 // dtc reply primitive h<->m
+#define T_REQUEST_T_C 0x86 // request transport connection primitive h<--m
+#define T_NEW_T_C 0x87 // new tc / reply to t_request primitive h-->m
+#define T_T_C_ERROR 0x77 // error creating tc primitive h-->m
+#define T_DATA_LAST 0xA0 // convey data from higher constructed h<->m
+ // layers
+#define T_DATA_MORE 0xA1 // convey data from higher constructed h<->m
+ // layers
+
+struct en50221_message {
+ struct en50221_message *next;
+ uint32_t length;
+ uint8_t data[0];
+};
+
+struct en50221_connection {
+ uint32_t state; // the current state: idle/in_delete/in_create/active
+ struct timeval tx_time; // time last request was sent from host->module, or 0 if ok
+ struct timeval last_poll_time; // time of last poll transmission
+ uint8_t *chain_buffer; // used to save parts of chained packets
+ uint32_t buffer_length;
+
+ struct en50221_message *send_queue;
+ struct en50221_message *send_queue_tail;
+};
+
+struct en50221_slot {
+ int ca_hndl;
+ uint8_t slot; // CAM slot
+ struct en50221_connection *connections;
+
+ pthread_mutex_t slot_lock;
+
+ uint32_t response_timeout;
+ uint32_t poll_delay;
+};
+
+struct en50221_transport_layer {
+ uint8_t max_slots;
+ uint8_t max_connections_per_slot;
+ struct en50221_slot *slots;
+ struct pollfd *slot_pollfds;
+ int slots_changed;
+
+ pthread_mutex_t global_lock;
+ pthread_mutex_t setcallback_lock;
+
+ int error;
+ int error_slot;
+
+ en50221_tl_callback callback;
+ void *callback_arg;
+};
+
+static int en50221_tl_process_data(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t * data,
+ uint32_t data_length);
+static int en50221_tl_poll_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id);
+static int en50221_tl_alloc_new_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id);
+static void queue_message(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ struct en50221_message *msg);
+static int en50221_tl_handle_create_tc_reply(struct en50221_transport_layer
+ *tl, uint8_t slot_id,
+ uint8_t connection_id);
+static int en50221_tl_handle_delete_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id);
+static int en50221_tl_handle_delete_tc_reply(struct en50221_transport_layer
+ *tl, uint8_t slot_id,
+ uint8_t connection_id);
+static int en50221_tl_handle_request_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id);
+static int en50221_tl_handle_data_more(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_tl_handle_data_last(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ uint8_t * data,
+ uint32_t data_length);
+static int en50221_tl_handle_sb(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ uint8_t * data, uint32_t data_length);
+
+
+struct en50221_transport_layer *en50221_tl_create(uint8_t max_slots,
+ uint8_t
+ max_connections_per_slot)
+{
+ struct en50221_transport_layer *tl = NULL;
+ int i;
+ int j;
+
+ // setup structure
+ tl = (struct en50221_transport_layer *)
+ malloc(sizeof(struct en50221_transport_layer));
+ if (tl == NULL)
+ goto error_exit;
+ tl->max_slots = max_slots;
+ tl->max_connections_per_slot = max_connections_per_slot;
+ tl->slots = NULL;
+ tl->slot_pollfds = NULL;
+ tl->slots_changed = 1;
+ tl->callback = NULL;
+ tl->callback_arg = NULL;
+ tl->error_slot = 0;
+ tl->error = 0;
+ pthread_mutex_init(&tl->global_lock, NULL);
+ pthread_mutex_init(&tl->setcallback_lock, NULL);
+
+ // create the slots
+ tl->slots = malloc(sizeof(struct en50221_slot) * max_slots);
+ if (tl->slots == NULL)
+ goto error_exit;
+
+ // set them up
+ for (i = 0; i < max_slots; i++) {
+ tl->slots[i].ca_hndl = -1;
+
+ // create the connections for this slot
+ tl->slots[i].connections =
+ malloc(sizeof(struct en50221_connection) * max_connections_per_slot);
+ if (tl->slots[i].connections == NULL)
+ goto error_exit;
+
+ // create a mutex for the slot
+ pthread_mutex_init(&tl->slots[i].slot_lock, NULL);
+
+ // set them up
+ for (j = 0; j < max_connections_per_slot; j++) {
+ tl->slots[i].connections[j].state = T_STATE_IDLE;
+ tl->slots[i].connections[j].tx_time.tv_sec = 0;
+ tl->slots[i].connections[j].last_poll_time.tv_sec = 0;
+ tl->slots[i].connections[j].last_poll_time.tv_usec = 0;
+ tl->slots[i].connections[j].chain_buffer = NULL;
+ tl->slots[i].connections[j].buffer_length = 0;
+ tl->slots[i].connections[j].send_queue = NULL;
+ tl->slots[i].connections[j].send_queue_tail = NULL;
+ }
+ }
+
+ // create the pollfds
+ tl->slot_pollfds = malloc(sizeof(struct pollfd) * max_slots);
+ if (tl->slot_pollfds == NULL) {
+ goto error_exit;
+ }
+ memset(tl->slot_pollfds, 0, sizeof(struct pollfd) * max_slots);
+
+ return tl;
+
+ error_exit:
+ en50221_tl_destroy(tl);
+ return NULL;
+}
+
+// Destroy an instance of the transport layer
+void en50221_tl_destroy(struct en50221_transport_layer *tl)
+{
+ int i, j;
+
+ if (tl) {
+ if (tl->slots) {
+ for (i = 0; i < tl->max_slots; i++) {
+ if (tl->slots[i].connections) {
+ for (j = 0; j < tl->max_connections_per_slot; j++) {
+ if (tl->slots[i].connections[j].chain_buffer) {
+ free(tl->slots[i].connections[j].chain_buffer);
+ }
+
+ struct en50221_message *cur_msg =
+ tl->slots[i].connections[j].send_queue;
+ while (cur_msg) {
+ struct en50221_message *next_msg = cur_msg->next;
+ free(cur_msg);
+ cur_msg = next_msg;
+ }
+ tl->slots[i].connections[j].send_queue = NULL;
+ tl->slots[i].connections[j].send_queue_tail = NULL;
+ }
+ free(tl->slots[i].connections);
+ pthread_mutex_destroy(&tl->slots[i].slot_lock);
+ }
+ }
+ free(tl->slots);
+ }
+ if (tl->slot_pollfds) {
+ free(tl->slot_pollfds);
+ }
+ pthread_mutex_destroy(&tl->setcallback_lock);
+ pthread_mutex_destroy(&tl->global_lock);
+ free(tl);
+ }
+}
+
+// this can be called from the user-space app to
+// register new slots that we should work with
+int en50221_tl_register_slot(struct en50221_transport_layer *tl,
+ int ca_hndl, uint8_t slot,
+ uint32_t response_timeout,
+ uint32_t poll_delay)
+{
+ // lock
+ pthread_mutex_lock(&tl->global_lock);
+
+ // we browse through the array of slots
+ // to look for the first unused one
+ int i;
+ int16_t slot_id = -1;
+ for (i = 0; i < tl->max_slots; i++) {
+ if (tl->slots[i].ca_hndl == -1) {
+ slot_id = i;
+ break;
+ }
+ }
+ if (slot_id == -1) {
+ tl->error = EN50221ERR_OUTOFSLOTS;
+ pthread_mutex_unlock(&tl->global_lock);
+ return -1;
+ }
+ // set up the slot struct
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ tl->slots[slot_id].ca_hndl = ca_hndl;
+ tl->slots[slot_id].slot = slot;
+ tl->slots[slot_id].response_timeout = response_timeout;
+ tl->slots[slot_id].poll_delay = poll_delay;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+
+ tl->slots_changed = 1;
+ pthread_mutex_unlock(&tl->global_lock);
+ return slot_id;
+}
+
+void en50221_tl_destroy_slot(struct en50221_transport_layer *tl,
+ uint8_t slot_id)
+{
+ int i;
+
+ if (slot_id >= tl->max_slots)
+ return;
+
+ // lock
+ pthread_mutex_lock(&tl->global_lock);
+
+ // clear the slot
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ tl->slots[slot_id].ca_hndl = -1;
+ for (i = 0; i < tl->max_connections_per_slot; i++) {
+ tl->slots[slot_id].connections[i].state = T_STATE_IDLE;
+ tl->slots[slot_id].connections[i].tx_time.tv_sec = 0;
+ tl->slots[slot_id].connections[i].last_poll_time.tv_sec = 0;
+ tl->slots[slot_id].connections[i].last_poll_time.tv_usec = 0;
+ if (tl->slots[slot_id].connections[i].chain_buffer) {
+ free(tl->slots[slot_id].connections[i].
+ chain_buffer);
+ }
+ tl->slots[slot_id].connections[i].chain_buffer = NULL;
+ tl->slots[slot_id].connections[i].buffer_length = 0;
+
+ struct en50221_message *cur_msg =
+ tl->slots[slot_id].connections[i].send_queue;
+ while (cur_msg) {
+ struct en50221_message *next_msg = cur_msg->next;
+ free(cur_msg);
+ cur_msg = next_msg;
+ }
+ tl->slots[slot_id].connections[i].send_queue = NULL;
+ tl->slots[slot_id].connections[i].send_queue_tail = NULL;
+ }
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+
+ // tell upper layers
+ pthread_mutex_lock(&tl->setcallback_lock);
+ en50221_tl_callback cb = tl->callback;
+ void *cb_arg = tl->callback_arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+ if (cb)
+ cb(cb_arg, T_CALLBACK_REASON_SLOTCLOSE, NULL, 0, slot_id, 0);
+
+ tl->slots_changed = 1;
+ pthread_mutex_unlock(&tl->global_lock);
+}
+
+int en50221_tl_poll(struct en50221_transport_layer *tl)
+{
+ uint8_t data[4096];
+ int slot_id;
+ int j;
+
+ // make up pollfds if the slots have changed
+ pthread_mutex_lock(&tl->global_lock);
+ if (tl->slots_changed) {
+ for (slot_id = 0; slot_id < tl->max_slots; slot_id++) {
+ if (tl->slots[slot_id].ca_hndl != -1) {
+ tl->slot_pollfds[slot_id].fd = tl->slots[slot_id].ca_hndl;
+ tl->slot_pollfds[slot_id].events = POLLIN | POLLPRI | POLLERR;
+ tl->slot_pollfds[slot_id].revents = 0;
+ } else {
+ tl->slot_pollfds[slot_id].fd = 0;
+ tl->slot_pollfds[slot_id].events = 0;
+ tl->slot_pollfds[slot_id].revents = 0;
+ }
+ }
+ tl->slots_changed = 0;
+ }
+ pthread_mutex_unlock(&tl->global_lock);
+
+ // anything happened?
+ if (poll(tl->slot_pollfds, tl->max_slots, 10) < 0) {
+ tl->error_slot = -1;
+ tl->error = EN50221ERR_CAREAD;
+ return -1;
+ }
+ // go through all slots (even though poll may not have reported any events
+ for (slot_id = 0; slot_id < tl->max_slots; slot_id++) {
+
+ // check if this slot is still used and get its handle
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ if (tl->slots[slot_id].ca_hndl == -1) {
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ continue;
+ }
+ int ca_hndl = tl->slots[slot_id].ca_hndl;
+
+ if (tl->slot_pollfds[slot_id].revents & (POLLPRI | POLLIN)) {
+ // read data
+ uint8_t r_slot_id;
+ uint8_t connection_id;
+ int readcnt = dvbca_link_read(ca_hndl, &r_slot_id,
+ &connection_id,
+ data, sizeof(data));
+ if (readcnt < 0) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAREAD;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // process it if we got some
+ if (readcnt > 0) {
+ if (tl->slots[slot_id].slot != r_slot_id) {
+ // this message is for an other CAM of the same CA
+ int new_slot_id;
+ for (new_slot_id = 0; new_slot_id < tl->max_slots; new_slot_id++) {
+ if ((tl->slots[new_slot_id].ca_hndl == ca_hndl) &&
+ (tl->slots[new_slot_id].slot == r_slot_id))
+ break;
+ }
+ if (new_slot_id != tl->max_slots) {
+ // we found the requested CAM
+ pthread_mutex_lock(&tl->slots[new_slot_id].slot_lock);
+ if (en50221_tl_process_data(tl, new_slot_id, data, readcnt)) {
+ pthread_mutex_unlock(&tl->slots[new_slot_id].slot_lock);
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ pthread_mutex_unlock(&tl->slots[new_slot_id].slot_lock);
+ } else {
+ tl->error = EN50221ERR_BADSLOTID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ } else
+ if (en50221_tl_process_data(tl, slot_id, data, readcnt)) {
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ }
+ } else if (tl->slot_pollfds[slot_id].revents & POLLERR) {
+ // an error was reported
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAREAD;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // poll the connections on this slot + check for timeouts
+ for (j = 0; j < tl->max_connections_per_slot; j++) {
+ // ignore connection if idle
+ if (tl->slots[slot_id].connections[j].state == T_STATE_IDLE) {
+ continue;
+ }
+ // send queued data
+ if (tl->slots[slot_id].connections[j].state &
+ (T_STATE_IN_CREATION | T_STATE_ACTIVE | T_STATE_ACTIVE_DELETEQUEUED)) {
+ // send data if there is some to go and we're not waiting for a response already
+ if (tl->slots[slot_id].connections[j].send_queue &&
+ (tl->slots[slot_id].connections[j].tx_time.tv_sec == 0)) {
+
+ // get the message
+ struct en50221_message *msg =
+ tl->slots[slot_id].connections[j].send_queue;
+ if (msg->next != NULL) {
+ tl->slots[slot_id].connections[j].send_queue = msg->next;
+ } else {
+ tl->slots[slot_id].connections[j].send_queue = NULL;
+ tl->slots[slot_id].connections[j].send_queue_tail = NULL;
+ }
+
+ // send the message
+ if (dvbca_link_write(tl->slots[slot_id].ca_hndl,
+ tl->slots[slot_id].slot,
+ j,
+ msg->data, msg->length) < 0) {
+ free(msg);
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ print(LOG_LEVEL, ERROR, 1, "CAWrite failed");
+ return -1;
+ }
+ gettimeofday(&tl->slots[slot_id].connections[j].tx_time, 0);
+
+ // fixup connection state for T_DELETE_T_C
+ if (msg->length && (msg->data[0] == T_DELETE_T_C)) {
+ tl->slots[slot_id].connections[j].state = T_STATE_IN_DELETION;
+ if (tl->slots[slot_id].connections[j].chain_buffer) {
+ free(tl->slots[slot_id].connections[j].chain_buffer);
+ }
+ tl->slots[slot_id].connections[j].chain_buffer = NULL;
+ tl->slots[slot_id].connections[j].buffer_length = 0;
+ }
+
+ free(msg);
+ }
+ }
+ // poll it if we're not expecting a reponse and the poll time has elapsed
+ if (tl->slots[slot_id].connections[j].state & T_STATE_ACTIVE) {
+ if ((tl->slots[slot_id].connections[j].tx_time.tv_sec == 0) &&
+ (time_after(tl->slots[slot_id].connections[j].last_poll_time,
+ tl->slots[slot_id].poll_delay))) {
+
+ gettimeofday(&tl->slots[slot_id].connections[j].last_poll_time, 0);
+ if (en50221_tl_poll_tc(tl, slot_id, j)) {
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ }
+ }
+
+ // check for timeouts - in any state
+ if (tl->slots[slot_id].connections[j].tx_time.tv_sec &&
+ (time_after(tl->slots[slot_id].connections[j].tx_time,
+ tl->slots[slot_id].response_timeout))) {
+
+ if (tl->slots[slot_id].connections[j].state &
+ (T_STATE_IN_CREATION |T_STATE_IN_DELETION)) {
+ tl->slots[slot_id].connections[j].state = T_STATE_IDLE;
+ } else if (tl->slots[slot_id].connections[j].state &
+ (T_STATE_ACTIVE | T_STATE_ACTIVE_DELETEQUEUED)) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_TIMEOUT;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ }
+ }
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ }
+
+ return 0;
+}
+
+void en50221_tl_register_callback(struct en50221_transport_layer *tl,
+ en50221_tl_callback callback, void *arg)
+{
+ pthread_mutex_lock(&tl->setcallback_lock);
+ tl->callback = callback;
+ tl->callback_arg = arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+}
+
+int en50221_tl_get_error_slot(struct en50221_transport_layer *tl)
+{
+ return tl->error_slot;
+}
+
+int en50221_tl_get_error(struct en50221_transport_layer *tl)
+{
+ return tl->error;
+}
+
+int en50221_tl_send_data(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ uint8_t * data, uint32_t data_size)
+{
+#ifdef DEBUG_TXDATA
+ printf("[[[[[[[[[[[[[[[[[[[[\n");
+ uint32_t ii = 0;
+ for (ii = 0; ii < data_size; ii++) {
+ printf("%02x: %02x\n", ii, data[ii]);
+ }
+ printf("]]]]]]]]]]]]]]]]]]]]\n");
+#endif
+
+ if (slot_id >= tl->max_slots) {
+ tl->error = EN50221ERR_BADSLOTID;
+ return -1;
+ }
+
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ if (tl->slots[slot_id].ca_hndl == -1) {
+ tl->error = EN50221ERR_BADSLOTID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (connection_id >= tl->max_connections_per_slot) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (tl->slots[slot_id].connections[connection_id].state != T_STATE_ACTIVE) {
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // allocate msg structure
+ struct en50221_message *msg =
+ malloc(sizeof(struct en50221_message) + data_size + 10);
+ if (msg == NULL) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFMEMORY;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // make up data to send
+ int length_field_len;
+ msg->data[0] = T_DATA_LAST;
+ if ((length_field_len = asn_1_encode(data_size + 1, msg->data + 1, 3)) < 0) {
+ free(msg);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_ASNENCODE;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ msg->data[1 + length_field_len] = connection_id;
+ memcpy(msg->data + 1 + length_field_len + 1, data, data_size);
+ msg->length = 1 + length_field_len + 1 + data_size;
+
+ // queue it for transmission
+ queue_message(tl, slot_id, connection_id, msg);
+
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return 0;
+}
+
+int en50221_tl_send_datav(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ struct iovec *vector, int iov_count)
+{
+#ifdef DEBUG_TXDATA
+ printf("[[[[[[[[[[[[[[[[[[[[\n");
+ uint32_t ii = 0;
+ uint32_t iipos = 0;
+ for (ii = 0; ii < (uint32_t) iov_count; ii++) {
+ uint32_t jj;
+ for (jj = 0; jj < vector[ii].iov_len; jj++) {
+ printf("%02x: %02x\n", jj + iipos,
+ *((uint8_t *) (vector[ii].iov_base) + jj));
+ }
+ iipos += vector[ii].iov_len;
+ }
+ printf("]]]]]]]]]]]]]]]]]]]]\n");
+#endif
+
+ if (slot_id >= tl->max_slots) {
+ tl->error = EN50221ERR_BADSLOTID;
+ return -1;
+ }
+
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ if (tl->slots[slot_id].ca_hndl == -1) {
+ tl->error = EN50221ERR_BADSLOTID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (connection_id >= tl->max_connections_per_slot) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (tl->slots[slot_id].connections[connection_id].state != T_STATE_ACTIVE) {
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // calculate the total length of the data to send
+ uint32_t data_size = 0;
+ int i;
+ for (i = 0; i < iov_count; i++) {
+ data_size += vector[i].iov_len;
+ }
+
+ // allocate msg structure
+ struct en50221_message *msg =
+ malloc(sizeof(struct en50221_message) + data_size + 10);
+ if (msg == NULL) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFMEMORY;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // make up data to send
+ int length_field_len;
+ msg->data[0] = T_DATA_LAST;
+ if ((length_field_len = asn_1_encode(data_size + 1, msg->data + 1, 3)) < 0) {
+ free(msg);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_ASNENCODE;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ msg->data[1 + length_field_len] = connection_id;
+ msg->length = 1 + length_field_len + 1 + data_size;
+ msg->next = NULL;
+
+ // merge the iovecs
+ uint32_t pos = 1 + length_field_len + 1;
+ for (i = 0; i < iov_count; i++) {
+ memcpy(msg->data + pos, vector[i].iov_base,
+ vector[i].iov_len);
+ pos += vector[i].iov_len;
+ }
+
+ // queue it for transmission
+ queue_message(tl, slot_id, connection_id, msg);
+
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return 0;
+}
+
+int en50221_tl_new_tc(struct en50221_transport_layer *tl, uint8_t slot_id)
+{
+ // check
+ if (slot_id >= tl->max_slots) {
+ tl->error = EN50221ERR_BADSLOTID;
+ return -1;
+ }
+
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ if (tl->slots[slot_id].ca_hndl == -1) {
+ tl->error = EN50221ERR_BADSLOTID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // allocate a new connection if possible
+ int conid = en50221_tl_alloc_new_tc(tl, slot_id);
+ if (conid == -1) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFCONNECTIONS;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // allocate msg structure
+ struct en50221_message *msg =
+ malloc(sizeof(struct en50221_message) + 3);
+ if (msg == NULL) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFMEMORY;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // make up the data to send
+ msg->data[0] = T_CREATE_T_C;
+ msg->data[1] = 1;
+ msg->data[2] = conid;
+ msg->length = 3;
+ msg->next = NULL;
+
+ // queue it for transmission
+ queue_message(tl, slot_id, conid, msg);
+
+ // done
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return conid;
+}
+
+int en50221_tl_del_tc(struct en50221_transport_layer *tl, uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // check
+ if (slot_id >= tl->max_slots) {
+ tl->error = EN50221ERR_BADSLOTID;
+ return -1;
+ }
+
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ if (tl->slots[slot_id].ca_hndl == -1) {
+ tl->error = EN50221ERR_BADSLOTID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (connection_id >= tl->max_connections_per_slot) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (!(tl->slots[slot_id].connections[connection_id].state &
+ (T_STATE_ACTIVE | T_STATE_IN_DELETION))) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADSTATE;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // allocate msg structure
+ struct en50221_message *msg =
+ malloc(sizeof(struct en50221_message) + 3);
+ if (msg == NULL) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFMEMORY;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ // make up the data to send
+ msg->data[0] = T_DELETE_T_C;
+ msg->data[1] = 1;
+ msg->data[2] = connection_id;
+ msg->length = 3;
+ msg->next = NULL;
+
+ // queue it for transmission
+ queue_message(tl, slot_id, connection_id, msg);
+ tl->slots[slot_id].connections[connection_id].state =
+ T_STATE_ACTIVE_DELETEQUEUED;
+
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return 0;
+}
+
+int en50221_tl_get_connection_state(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id)
+{
+ if (slot_id >= tl->max_slots) {
+ tl->error = EN50221ERR_BADSLOTID;
+ return -1;
+ }
+
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ if (tl->slots[slot_id].ca_hndl == -1) {
+ tl->error = EN50221ERR_BADSLOTID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ if (connection_id >= tl->max_connections_per_slot) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+ return -1;
+ }
+ int state = tl->slots[slot_id].connections[connection_id].state;
+ pthread_mutex_unlock(&tl->slots[slot_id].slot_lock);
+
+ return state;
+}
+
+
+
+
+// ask the module for new data
+static int en50221_tl_poll_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id)
+{
+ gettimeofday(&tl->slots[slot_id].connections[connection_id].
+ tx_time, 0);
+
+ // send command
+ uint8_t hdr[3];
+ hdr[0] = T_DATA_LAST;
+ hdr[1] = 1;
+ hdr[2] = connection_id;
+ if (dvbca_link_write(tl->slots[slot_id].ca_hndl,
+ tl->slots[slot_id].slot,
+ connection_id, hdr, 3) < 0) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ return -1;
+ }
+ return 0;
+}
+
+// handle incoming data
+static int en50221_tl_process_data(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t * data,
+ uint32_t data_length)
+{
+ int result;
+
+#ifdef DEBUG_RXDATA
+ printf("-------------------\n");
+ uint32_t ii = 0;
+ for (ii = 0; ii < data_length; ii++) {
+ printf("%02x: %02x\n", ii, data[ii]);
+ }
+ printf("+++++++++++++++++++\n");
+#endif
+
+ // process the received data
+ while (data_length) {
+ // parse the header
+ uint8_t tpdu_tag = data[0];
+ uint16_t asn_data_length;
+ int length_field_len;
+ if ((length_field_len = asn_1_decode(&asn_data_length, data + 1, data_length - 1)) < 0) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid asn from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+ if ((asn_data_length < 1) ||
+ (asn_data_length > (data_length - (1 + length_field_len)))) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received data with invalid length from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+ uint8_t connection_id = data[1 + length_field_len];
+ data += 1 + length_field_len + 1;
+ data_length -= (1 + length_field_len + 1);
+ asn_data_length--;
+
+ // check the connection_id
+ if (connection_id >= tl->max_connections_per_slot) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received bad connection id %02x from module on slot %02x\n",
+ connection_id, slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCONNECTIONID;
+ return -1;
+ }
+ // process the TPDUs
+ switch (tpdu_tag) {
+ case T_C_T_C_REPLY:
+ if ((result = en50221_tl_handle_create_tc_reply(tl, slot_id, connection_id)) < 0) {
+ return -1;
+ }
+ break;
+ case T_DELETE_T_C:
+ if ((result = en50221_tl_handle_delete_tc(tl, slot_id, connection_id)) < 0) {
+ return -1;
+ }
+ break;
+ case T_D_T_C_REPLY:
+ if ((result = en50221_tl_handle_delete_tc_reply(tl, slot_id, connection_id)) < 0) {
+ return -1;
+ }
+ break;
+ case T_REQUEST_T_C:
+ if ((result = en50221_tl_handle_request_tc(tl, slot_id, connection_id)) < 0) {
+ return -1;
+ }
+ break;
+ case T_DATA_MORE:
+ if ((result = en50221_tl_handle_data_more(tl, slot_id,
+ connection_id,
+ data,
+ asn_data_length)) < 0) {
+ return -1;
+ }
+ break;
+ case T_DATA_LAST:
+ if ((result = en50221_tl_handle_data_last(tl, slot_id,
+ connection_id,
+ data,
+ asn_data_length)) < 0) {
+ return -1;
+ }
+ break;
+ case T_SB:
+ if ((result = en50221_tl_handle_sb(tl, slot_id,
+ connection_id,
+ data,
+ asn_data_length)) < 0) {
+ return -1;
+ }
+ break;
+ default:
+ print(LOG_LEVEL, ERROR, 1,
+ "Recieved unexpected TPDU tag %02x from module on slot %02x\n",
+ tpdu_tag, slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+
+ // skip over the consumed data
+ data += asn_data_length;
+ data_length -= asn_data_length;
+ }
+
+ return 0;
+}
+
+static int en50221_tl_handle_create_tc_reply(struct en50221_transport_layer
+ *tl, uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // set this connection to state active
+ if (tl->slots[slot_id].connections[connection_id].state == T_STATE_IN_CREATION) {
+ tl->slots[slot_id].connections[connection_id].state = T_STATE_ACTIVE;
+ tl->slots[slot_id].connections[connection_id].tx_time.tv_sec = 0;
+
+ // tell upper layers
+ pthread_mutex_lock(&tl->setcallback_lock);
+ en50221_tl_callback cb = tl->callback;
+ void *cb_arg = tl->callback_arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+ if (cb)
+ cb(cb_arg, T_CALLBACK_REASON_CONNECTIONOPEN, NULL, 0, slot_id, connection_id);
+ } else {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received T_C_T_C_REPLY for connection not in "
+ "T_STATE_IN_CREATION from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int en50221_tl_handle_delete_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // immediately delete this connection and send D_T_C_REPLY
+ if (tl->slots[slot_id].connections[connection_id].state &
+ (T_STATE_ACTIVE | T_STATE_IN_DELETION)) {
+ // clear down the slot
+ tl->slots[slot_id].connections[connection_id].state = T_STATE_IDLE;
+ if (tl->slots[slot_id].connections[connection_id].chain_buffer) {
+ free(tl->slots[slot_id].connections[connection_id].chain_buffer);
+ }
+ tl->slots[slot_id].connections[connection_id].chain_buffer = NULL;
+ tl->slots[slot_id].connections[connection_id].buffer_length = 0;
+
+ // send the reply
+ uint8_t hdr[3];
+ hdr[0] = T_D_T_C_REPLY;
+ hdr[1] = 1;
+ hdr[2] = connection_id;
+ if (dvbca_link_write(tl->slots[slot_id].ca_hndl,
+ tl->slots[slot_id].slot,
+ connection_id, hdr, 3) < 0) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ return -1;
+ }
+ // tell upper layers
+ pthread_mutex_lock(&tl->setcallback_lock);
+ en50221_tl_callback cb = tl->callback;
+ void *cb_arg = tl->callback_arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+ if (cb)
+ cb(cb_arg, T_CALLBACK_REASON_CONNECTIONCLOSE, NULL, 0, slot_id, connection_id);
+ } else {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received T_DELETE_T_C for inactive connection from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int en50221_tl_handle_delete_tc_reply(struct en50221_transport_layer
+ *tl, uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // delete this connection, should be in T_STATE_IN_DELETION already
+ if (tl->slots[slot_id].connections[connection_id].state == T_STATE_IN_DELETION) {
+ tl->slots[slot_id].connections[connection_id].state = T_STATE_IDLE;
+ } else {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received T_D_T_C_REPLY received for connection not in "
+ "T_STATE_IN_DELETION from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int en50221_tl_handle_request_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id)
+{
+ // allocate a new connection if possible
+ int conid = en50221_tl_alloc_new_tc(tl, slot_id);
+ int ca_hndl = tl->slots[slot_id].ca_hndl;
+ if (conid == -1) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Too many connections requested by module on slot %02x\n",
+ slot_id);
+
+ // send the error
+ uint8_t hdr[4];
+ hdr[0] = T_T_C_ERROR;
+ hdr[1] = 2;
+ hdr[2] = connection_id;
+ hdr[3] = 1;
+ if (dvbca_link_write(ca_hndl, tl->slots[slot_id].slot, connection_id, hdr, 4) < 0) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ return -1;
+ }
+ tl->slots[slot_id].connections[connection_id].tx_time.
+ tv_sec = 0;
+ } else {
+ // send the NEW_T_C on the connection we received it on
+ uint8_t hdr[4];
+ hdr[0] = T_NEW_T_C;
+ hdr[1] = 2;
+ hdr[2] = connection_id;
+ hdr[3] = conid;
+ if (dvbca_link_write(ca_hndl, tl->slots[slot_id].slot, connection_id, hdr, 4) < 0) {
+ tl->slots[slot_id].connections[conid].state = T_STATE_IDLE;
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ return -1;
+ }
+ tl->slots[slot_id].connections[connection_id].tx_time.tv_sec = 0;
+
+ // send the CREATE_T_C on the new connnection
+ hdr[0] = T_CREATE_T_C;
+ hdr[1] = 1;
+ hdr[2] = conid;
+ if (dvbca_link_write(ca_hndl, tl->slots[slot_id].slot, conid, hdr, 3) < 0) {
+ tl->slots[slot_id].connections[conid].state = T_STATE_IDLE;
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ return -1;
+ }
+ gettimeofday(&tl->slots[slot_id].connections[conid].tx_time, 0);
+
+ // tell upper layers
+ pthread_mutex_lock(&tl->setcallback_lock);
+ en50221_tl_callback cb = tl->callback;
+ void *cb_arg = tl->callback_arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+ if (cb)
+ cb(cb_arg, T_CALLBACK_REASON_CAMCONNECTIONOPEN, NULL, 0, slot_id, conid);
+ }
+
+ return 0;
+}
+
+static int en50221_tl_handle_data_more(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // connection in correct state?
+ if (tl->slots[slot_id].connections[connection_id].state != T_STATE_ACTIVE) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received T_DATA_MORE for connection not in "
+ "T_STATE_ACTIVE from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+ // a chained data packet is coming in, save
+ // it to the buffer and wait for more
+ tl->slots[slot_id].connections[connection_id].tx_time.tv_sec = 0;
+ int new_data_length =
+ tl->slots[slot_id].connections[connection_id].buffer_length + data_length;
+ uint8_t *new_data_buffer =
+ realloc(tl->slots[slot_id].connections[connection_id].chain_buffer, new_data_length);
+ if (new_data_buffer == NULL) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFMEMORY;
+ return -1;
+ }
+ tl->slots[slot_id].connections[connection_id].chain_buffer = new_data_buffer;
+
+ memcpy(tl->slots[slot_id].connections[connection_id].chain_buffer +
+ tl->slots[slot_id].connections[connection_id].buffer_length,
+ data, data_length);
+ tl->slots[slot_id].connections[connection_id].buffer_length = new_data_length;
+
+ return 0;
+}
+
+static int en50221_tl_handle_data_last(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ uint8_t * data,
+ uint32_t data_length)
+{
+ // connection in correct state?
+ if (tl->slots[slot_id].connections[connection_id].state != T_STATE_ACTIVE) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received T_DATA_LAST received for connection not in "
+ "T_STATE_ACTIVE from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+ // last package of a chain or single package comes in
+ tl->slots[slot_id].connections[connection_id].tx_time.tv_sec = 0;
+ if (tl->slots[slot_id].connections[connection_id].chain_buffer == NULL) {
+ // single package => dispatch immediately
+ pthread_mutex_lock(&tl->setcallback_lock);
+ en50221_tl_callback cb = tl->callback;
+ void *cb_arg = tl->callback_arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+
+ if (cb && data_length) {
+ pthread_mutex_unlock(&tl->slots[slot_id].
+ slot_lock);
+ cb(cb_arg, T_CALLBACK_REASON_DATA, data, data_length, slot_id, connection_id);
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ }
+ } else {
+ int new_data_length =
+ tl->slots[slot_id].connections[connection_id].buffer_length + data_length;
+ uint8_t *new_data_buffer =
+ realloc(tl->slots[slot_id].connections[connection_id].chain_buffer, new_data_length);
+ if (new_data_buffer == NULL) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_OUTOFMEMORY;
+ return -1;
+ }
+
+ memcpy(new_data_buffer +
+ tl->slots[slot_id].connections[connection_id].
+ buffer_length, data, data_length);
+
+ // clean the buffer position
+ tl->slots[slot_id].connections[connection_id].chain_buffer = NULL;
+ tl->slots[slot_id].connections[connection_id].buffer_length = 0;
+
+ // tell the upper layers
+ pthread_mutex_lock(&tl->setcallback_lock);
+ en50221_tl_callback cb = tl->callback;
+ void *cb_arg = tl->callback_arg;
+ pthread_mutex_unlock(&tl->setcallback_lock);
+ if (cb && data_length) {
+ pthread_mutex_unlock(&tl->slots[slot_id].
+ slot_lock);
+ cb(cb_arg, T_CALLBACK_REASON_DATA, new_data_buffer,
+ new_data_length, slot_id, connection_id);
+ pthread_mutex_lock(&tl->slots[slot_id].slot_lock);
+ }
+
+ free(new_data_buffer);
+ }
+
+ return 0;
+}
+
+static int en50221_tl_handle_sb(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ uint8_t * data, uint32_t data_length)
+{
+ // is the connection id ok?
+ if (tl->slots[slot_id].connections[connection_id].state != T_STATE_ACTIVE) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Received T_SB for connection not in T_STATE_ACTIVE from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+ // did we get enough data in the T_SB?
+ if (data_length != 1) {
+ print(LOG_LEVEL, ERROR, 1,
+ "Recieved T_SB with invalid length from module on slot %02x\n",
+ slot_id);
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_BADCAMDATA;
+ return -1;
+ }
+ // tell it to send the data if it says there is some
+ if (data[0] & 0x80) {
+ int ca_hndl = tl->slots[slot_id].ca_hndl;
+
+ // send the RCV
+ uint8_t hdr[3];
+ hdr[0] = T_RCV;
+ hdr[1] = 1;
+ hdr[2] = connection_id;
+ if (dvbca_link_write(ca_hndl, tl->slots[slot_id].slot, connection_id, hdr, 3) < 0) {
+ tl->error_slot = slot_id;
+ tl->error = EN50221ERR_CAWRITE;
+ return -1;
+ }
+ gettimeofday(&tl->slots[slot_id].connections[connection_id].tx_time, 0);
+
+ } else {
+ // no data - indicate not waiting for anything now
+ tl->slots[slot_id].connections[connection_id].tx_time.tv_sec = 0;
+ }
+
+ return 0;
+}
+
+static int en50221_tl_alloc_new_tc(struct en50221_transport_layer *tl,
+ uint8_t slot_id)
+{
+ // we browse through the array of connection
+ // types, to look for the first unused one
+ int i, conid = -1;
+ for (i = 1; i < tl->max_connections_per_slot; i++) {
+ if (tl->slots[slot_id].connections[i].state == T_STATE_IDLE) {
+ conid = i;
+ break;
+ }
+ }
+ if (conid == -1) {
+ print(LOG_LEVEL, ERROR, 1,
+ "CREATE_T_C failed: no more connections available\n");
+ return -1;
+ }
+ // set up the connection struct
+ tl->slots[slot_id].connections[conid].state = T_STATE_IN_CREATION;
+ tl->slots[slot_id].connections[conid].chain_buffer = NULL;
+ tl->slots[slot_id].connections[conid].buffer_length = 0;
+
+ return conid;
+}
+
+static void queue_message(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ struct en50221_message *msg)
+{
+ msg->next = NULL;
+ if (tl->slots[slot_id].connections[connection_id].send_queue_tail) {
+ tl->slots[slot_id].connections[connection_id].send_queue_tail->next = msg;
+ tl->slots[slot_id].connections[connection_id].send_queue_tail = msg;
+ } else {
+ tl->slots[slot_id].connections[connection_id].send_queue = msg;
+ tl->slots[slot_id].connections[connection_id].send_queue_tail = msg;
+ }
+}
diff --git a/lib/libdvben50221/en50221_transport.h b/lib/libdvben50221/en50221_transport.h
new file mode 100644
index 0000000..7882060
--- /dev/null
+++ b/lib/libdvben50221/en50221_transport.h
@@ -0,0 +1,234 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 session layer
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef __EN50221_TRANSPORT_H__
+#define __EN50221_TRANSPORT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/uio.h>
+
+/**
+ * Callback reasons.
+ */
+#define T_CALLBACK_REASON_CONNECTIONOPEN 0x00 // A connection we opened _to_ the cam has been ACKed
+#define T_CALLBACK_REASON_CAMCONNECTIONOPEN 0x01 // The cam has opened a connection to _us_.
+#define T_CALLBACK_REASON_DATA 0x02 // Data received
+#define T_CALLBACK_REASON_CONNECTIONCLOSE 0x03 // The cam has told us to close a connection.
+#define T_CALLBACK_REASON_SLOTCLOSE 0x04 // The cam in the supplied slot id has been removed.
+
+// these are the states a TC can be in
+#define T_STATE_IDLE 0x01 // this transport connection is not in use
+#define T_STATE_ACTIVE 0x02 // this transport connection is in use
+#define T_STATE_ACTIVE_DELETEQUEUED 0x04 // this transport connection is about to be deleted
+#define T_STATE_IN_CREATION 0x08 // this transport waits for a T_C_T_C_REPLY to become active
+#define T_STATE_IN_DELETION 0x10 // this transport waits for T_D_T_C_REPLY to become idle again
+
+/**
+ * Opaque type representing a transport layer.
+ */
+struct en50221_transport_layer;
+
+/**
+ * Type definition for callback function - used when events are received from a module.
+ *
+ * **IMPORTANT** For all callback reasons except T_CALLBACK_REASON_DATA, an internal lock is held in the
+ * transport layer. Therefore, to avoid deadlock, you *must not* call back into the transport layer for
+ * these reasons.
+ *
+ * However, for T_CALLBACK_REASON_DATA, the internal lock is not held, so calling back into the transport
+ * layer is fine in this case.
+ *
+ * @param arg Private data.
+ * @param reason One of the T_CALLBACK_REASON_* values.
+ * @param data The data.
+ * @param data_length Length of the data.
+ * @param slot_id Slot_id the data was received from.
+ * @param connection_id Connection_id the data was received from.
+ */
+typedef void (*en50221_tl_callback) (void *arg, int reason,
+ uint8_t * data,
+ uint32_t data_length,
+ uint8_t slot_id,
+ uint8_t connection_id);
+
+
+/**
+ * Construct a new instance of the transport layer.
+ *
+ * @param max_slots Maximum number of slots to support.
+ * @param max_connections_per_slot Maximum connections per slot.
+ * @return The en50221_transport_layer instance, or NULL on error.
+ */
+extern struct en50221_transport_layer *en50221_tl_create(uint8_t max_slots,
+ uint8_t max_connections_per_slot);
+
+/**
+ * Destroy an instance of the transport layer.
+ *
+ * @param tl The en50221_transport_layer instance.
+ */
+extern void en50221_tl_destroy(struct en50221_transport_layer *tl);
+
+/**
+ * Register a new slot with the library.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param ca_hndl FD for talking to the slot.
+ * @param slot CAM slot where the requested CAM of the CA is in.
+ * @param response_timeout Maximum timeout in ms to a response we send before signalling a timeout.
+ * @param poll_delay Interval between polls in ms.
+ * @return slot_id on sucess, or -1 on error.
+ */
+extern int en50221_tl_register_slot(struct en50221_transport_layer *tl,
+ int ca_hndl, uint8_t slot,
+ uint32_t response_timeout,
+ uint32_t poll_delay);
+
+/**
+ * Destroy a registered slot - e.g. if a CAM is removed, or an error occurs. Does
+ * not attempt to reset the CAM.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param slot_id Slot to destroy.
+ */
+extern void en50221_tl_destroy_slot(struct en50221_transport_layer *tl, uint8_t slot_id);
+
+/**
+ * Performs one iteration of the transport layer poll -
+ * checking for incoming data furthermore it will handle
+ * the timeouts of certain commands like T_DELETE_T_C it
+ * should be called by the application regularly, generally
+ * faster than the poll delay.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @return 0 on succes, or -1 if there was an error of some sort.
+ */
+extern int en50221_tl_poll(struct en50221_transport_layer *tl);
+
+/**
+ * Register the callback for data reception.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param callback The callback. Set to NULL to remove the callback completely.
+ * @param arg Private data passed as arg0 of the callback.
+ */
+extern void en50221_tl_register_callback(struct en50221_transport_layer *tl,
+ en50221_tl_callback callback, void *arg);
+
+/**
+ * Gets the ID of the slot an error occurred on.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @return The offending slot id.
+ */
+extern int en50221_tl_get_error_slot(struct en50221_transport_layer *tl);
+
+/**
+ * Gets the last error.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @return One of the EN50221ERR_* values.
+ */
+extern int en50221_tl_get_error(struct en50221_transport_layer *tl);
+
+/**
+ * This function is used to take a data-block, pack into
+ * into a TPDU (DATA_LAST) and send it to the device
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param slot_id ID of the slot.
+ * @param connection_id Connection id.
+ * @param data Data to send.
+ * @param data_length Number of bytes to send.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_tl_send_data(struct en50221_transport_layer *tl,
+ uint8_t slot_id,
+ uint8_t connection_id,
+ uint8_t * data,
+ uint32_t data_length);
+
+/**
+ * This function is used to take a data-block, pack into
+ * into a TPDU (DATA_LAST) and send it to the device
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param slot_id ID of the slot.
+ * @param connection_id Connection id.
+ * @param vector iov to send.
+ * @param io_count Number of elements in vector.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_tl_send_datav(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id,
+ struct iovec *vector, int iov_count);
+
+/**
+ * Create a new transport connection to the cam.
+ *
+ * **IMPORTANT** When this function returns, it means the request to create a connection
+ * has been submitted. You will need to poll using en50221_tl_get_connection_state() to find out
+ * if/when the connection is established. A callback with T_CALLBACK_REASON_CONNECTIONOPEN reason
+ * will also be sent when it is acked by the CAM.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param slot_id ID of the slot.
+ * @return The allocated connection id on success, or -1 on error.
+ */
+extern int en50221_tl_new_tc(struct en50221_transport_layer *tl, uint8_t slot_id);
+
+/**
+ * Deallocates a transport connection.
+ *
+ * **IMPORTANT** When this function returns, it means the request to destroy a connection
+ * has been submitted. You will need to poll using en50221_tl_get_connection_state() to find out
+ * if/when the connection is destroyed.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param slot_id ID of the slot.
+ * @param connection_id Connection id to send the request _on_.
+ * @return 0 on success, or -1 on error.
+ */
+extern int en50221_tl_del_tc(struct en50221_transport_layer *tl, uint8_t slot_id, uint8_t connection_id);
+
+/**
+ * Checks the state of a connection.
+ *
+ * @param tl The en50221_transport_layer instance.
+ * @param slot_id ID of the slot.
+ * @param connection_id Connection id to send the request _on_.
+ * @return One of the T_STATE_* values.
+ */
+extern int en50221_tl_get_connection_state(struct en50221_transport_layer *tl,
+ uint8_t slot_id, uint8_t connection_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/libdvbmisc/dvbmisc.h b/lib/libdvbmisc/dvbmisc.h
new file mode 100644
index 0000000..8ac6eee
--- /dev/null
+++ b/lib/libdvbmisc/dvbmisc.h
@@ -0,0 +1,72 @@
+/*
+ libdvbmisc - DVB miscellaneous library
+
+ Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef DVB_MISC_H
+#define DVB_MISC_H
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define ERROR 0
+#define NOTICE 1
+#define INFO 2
+#define DEBUG 3
+
+#define print(x, y, z, fmt, arg...) do { \
+ if (z) { \
+ if ((x > ERROR) && (x > y)) \
+ vprint("%s: " fmt "\n", __func__ , ##arg); \
+ else if ((x > NOTICE) && (x > y)) \
+ vprint("%s: " fmt "\n",__func__ , ##arg); \
+ else if ((x > INFO) && (x > y)) \
+ vprint("%s: " fmt "\n", __func__ , ##arg); \
+ else if ((x > DEBUG) && (x > y)) \
+ vprint("%s: " fmt "\n", __func__ , ##arg); \
+ } else { \
+ if (x > y) \
+ vprint(fmt, ##arg); \
+ } \
+} while(0)
+
+static inline void vprint(char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+static inline int time_after(struct timeval oldtime, uint32_t delta_ms)
+{
+ // calculate the oldtime + add on the delta
+ uint64_t oldtime_ms = (oldtime.tv_sec * 1000) + (oldtime.tv_usec / 1000);
+ oldtime_ms += delta_ms;
+
+ // calculate the nowtime
+ struct timeval nowtime;
+ gettimeofday(&nowtime, 0);
+ uint64_t nowtime_ms = (nowtime.tv_sec * 1000) + (nowtime.tv_usec / 1000);
+
+ // check
+ return nowtime_ms > oldtime_ms;
+}
+
+#endif
diff --git a/lib/libdvbsec/Makefile b/lib/libdvbsec/Makefile
new file mode 100644
index 0000000..3d405f4
--- /dev/null
+++ b/lib/libdvbsec/Makefile
@@ -0,0 +1,17 @@
+# Makefile for linuxtv.org dvb-apps/lib/libdvbsec
+
+includes = dvbsec_api.h \
+ dvbsec_cfg.h
+
+objects = dvbsec_api.o \
+ dvbsec_cfg.o
+
+lib_name = libdvbsec
+
+CPPFLAGS += -I../../lib
+
+.PHONY: all
+
+all: library
+
+include ../../Make.rules
diff --git a/lib/libdvbsec/dvbsec_api.c b/lib/libdvbsec/dvbsec_api.c
new file mode 100644
index 0000000..5f2ae22
--- /dev/null
+++ b/lib/libdvbsec/dvbsec_api.c
@@ -0,0 +1,951 @@
+/*
+ libdvbsec - an SEC library
+
+ Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <linux/types.h>
+#include <libdvbapi/dvbfe.h>
+#include "dvbsec_api.h"
+
+// uncomment this to make dvbsec_command print out debug instead of talking to a frontend
+// #define TEST_SEC_COMMAND 1
+
+int dvbsec_set(struct dvbfe_handle *fe,
+ struct dvbsec_config *sec_config,
+ enum dvbsec_diseqc_polarization polarization,
+ enum dvbsec_diseqc_switch sat_pos,
+ enum dvbsec_diseqc_switch switch_option,
+ struct dvbfe_parameters *params,
+ int timeout)
+{
+ int tmp;
+ struct dvbfe_parameters localparams;
+ struct dvbfe_parameters *topass = params;
+
+ // perform SEC
+ if (sec_config != NULL) {
+ switch(sec_config->config_type) {
+ case DVBSEC_CONFIG_NONE:
+ break;
+
+ case DVBSEC_CONFIG_POWER:
+ dvbfe_set_voltage(fe, DVBFE_SEC_VOLTAGE_13);
+ break;
+
+ case DVBSEC_CONFIG_STANDARD:
+ {
+ // calculate the correct oscillator value
+ enum dvbsec_diseqc_oscillator osc = DISEQC_OSCILLATOR_LOW;
+ if (sec_config->switch_frequency && (sec_config->switch_frequency < params->frequency))
+ osc = DISEQC_OSCILLATOR_HIGH;
+
+ if ((tmp = dvbsec_std_sequence(fe,
+ osc,
+ polarization,
+ sat_pos,
+ switch_option)) < 0)
+ return tmp;
+ break;
+ }
+
+ case DVBSEC_CONFIG_ADVANCED:
+ {
+ // are we high or not?
+ int high = 0;
+ if (sec_config->switch_frequency && (sec_config->switch_frequency < params->frequency))
+ high = 1;
+
+ // determine correct string
+ char *cmd = NULL;
+ switch(polarization) {
+ case DISEQC_POLARIZATION_H:
+ if (!high)
+ cmd = sec_config->adv_cmd_lo_h;
+ else
+ cmd = sec_config->adv_cmd_hi_h;
+ break;
+ case DISEQC_POLARIZATION_V:
+ if (!high)
+ cmd = sec_config->adv_cmd_lo_v;
+ else
+ cmd = sec_config->adv_cmd_hi_v;
+ break;
+ case DISEQC_POLARIZATION_L:
+ if (!high)
+ cmd = sec_config->adv_cmd_lo_l;
+ else
+ cmd = sec_config->adv_cmd_hi_l;
+ break;
+ case DISEQC_POLARIZATION_R:
+ if (!high)
+ cmd = sec_config->adv_cmd_lo_r;
+ else
+ cmd = sec_config->adv_cmd_hi_r;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ // do it
+ if (cmd)
+ if ((tmp = dvbsec_command(fe, cmd)) < 0)
+ return tmp;
+ break;
+ }
+ }
+
+ // work out the correct LOF value
+ uint32_t lof = 0;
+ if ((sec_config->switch_frequency == 0) || (params->frequency < sec_config->switch_frequency)) {
+ // LOW band
+ switch(polarization) {
+ case DISEQC_POLARIZATION_H:
+ lof = sec_config->lof_lo_h;
+ break;
+ case DISEQC_POLARIZATION_V:
+ lof = sec_config->lof_lo_v;
+ break;
+ case DISEQC_POLARIZATION_L:
+ lof = sec_config->lof_lo_l;
+ break;
+ case DISEQC_POLARIZATION_R:
+ lof = sec_config->lof_lo_r;
+ break;
+ case DISEQC_POLARIZATION_UNCHANGED:
+ break;
+ }
+ } else {
+ // HIGH band
+ switch(polarization) {
+ case DISEQC_POLARIZATION_H:
+ lof = sec_config->lof_hi_h;
+ break;
+ case DISEQC_POLARIZATION_V:
+ lof = sec_config->lof_hi_v;
+ break;
+ case DISEQC_POLARIZATION_L:
+ lof = sec_config->lof_hi_l;
+ break;
+ case DISEQC_POLARIZATION_R:
+ lof = sec_config->lof_hi_r;
+ break;
+ case DISEQC_POLARIZATION_UNCHANGED:
+ break;
+ }
+ }
+
+ // do frequency adjustment
+ if (lof) {
+ memcpy(&localparams, params, sizeof(struct dvbfe_parameters));
+ int tmpfreq = localparams.frequency - lof;
+
+ if (tmpfreq < 0)
+ tmpfreq *= -1;
+ localparams.frequency = (uint32_t) tmpfreq;
+ topass = &localparams;
+ }
+ }
+
+ // set the frontend!
+ return dvbfe_set(fe, topass, timeout);
+}
+
+int dvbsec_std_sequence(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_oscillator oscillator,
+ enum dvbsec_diseqc_polarization polarization,
+ enum dvbsec_diseqc_switch sat_pos,
+ enum dvbsec_diseqc_switch switch_option)
+{
+ dvbfe_set_22k_tone(fe, DVBFE_SEC_TONE_OFF);
+
+ switch(polarization) {
+ case DISEQC_POLARIZATION_V:
+ case DISEQC_POLARIZATION_R:
+ dvbfe_set_voltage(fe, DVBFE_SEC_VOLTAGE_13);
+ break;
+ case DISEQC_POLARIZATION_H:
+ case DISEQC_POLARIZATION_L:
+ dvbfe_set_voltage(fe, DVBFE_SEC_VOLTAGE_18);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dvbsec_diseqc_set_committed_switches(fe,
+ DISEQC_ADDRESS_ANY_DEVICE,
+ oscillator,
+ polarization,
+ sat_pos,
+ switch_option);
+
+ usleep(15000);
+
+ switch(sat_pos) {
+ case DISEQC_SWITCH_A:
+ dvbfe_set_tone_data_burst(fe, DVBFE_SEC_MINI_A);
+ break;
+ case DISEQC_SWITCH_B:
+ dvbfe_set_tone_data_burst(fe, DVBFE_SEC_MINI_B);
+ break;
+ default:
+ break;
+ }
+
+ if (sat_pos != DISEQC_SWITCH_UNCHANGED)
+ usleep(15000);
+
+ switch(oscillator) {
+ case DISEQC_OSCILLATOR_LOW:
+ dvbfe_set_22k_tone(fe, DVBFE_SEC_TONE_OFF);
+ break;
+ case DISEQC_OSCILLATOR_HIGH:
+ dvbfe_set_22k_tone(fe, DVBFE_SEC_TONE_ON);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int dvbsec_diseqc_set_reset(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_reset state)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x00 };
+
+ if (state == DISEQC_RESET_CLEAR)
+ data[2] = 0x01;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_power(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_power state)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x02 };
+
+ if (state == DISEQC_POWER_ON)
+ data[2] = 0x03;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_listen(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_listen state)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x30 };
+
+ if (state == DISEQC_LISTEN_AWAKE)
+ data[2] = 0x31;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_committed_switches(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_oscillator oscillator,
+ enum dvbsec_diseqc_polarization polarization,
+ enum dvbsec_diseqc_switch sat_pos,
+ enum dvbsec_diseqc_switch switch_option)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x38, 0x00 };
+
+ switch(oscillator) {
+ case DISEQC_OSCILLATOR_LOW:
+ data[3] |= 0x10;
+ break;
+ case DISEQC_OSCILLATOR_HIGH:
+ data[3] |= 0x11;
+ break;
+ case DISEQC_OSCILLATOR_UNCHANGED:
+ break;
+ }
+ switch(polarization) {
+ case DISEQC_POLARIZATION_V:
+ case DISEQC_POLARIZATION_R:
+ data[3] |= 0x20;
+ break;
+ case DISEQC_POLARIZATION_H:
+ case DISEQC_POLARIZATION_L:
+ data[3] |= 0x22;
+ break;
+ default:
+ break;
+ }
+ switch(sat_pos) {
+ case DISEQC_SWITCH_A:
+ data[3] |= 0x40;
+ break;
+ case DISEQC_SWITCH_B:
+ data[3] |= 0x44;
+ break;
+ case DISEQC_SWITCH_UNCHANGED:
+ break;
+ }
+ switch(switch_option) {
+ case DISEQC_SWITCH_A:
+ data[3] |= 0x80;
+ break;
+ case DISEQC_SWITCH_B:
+ data[3] |= 0x88;
+ break;
+ case DISEQC_SWITCH_UNCHANGED:
+ break;
+ }
+
+ if (data[3] == 0)
+ return 0;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_uncommitted_switches(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_switch s1,
+ enum dvbsec_diseqc_switch s2,
+ enum dvbsec_diseqc_switch s3,
+ enum dvbsec_diseqc_switch s4)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x39, 0x00 };
+
+ switch(s1) {
+ case DISEQC_SWITCH_A:
+ data[3] |= 0x10;
+ break;
+ case DISEQC_SWITCH_B:
+ data[3] |= 0x11;
+ break;
+ case DISEQC_SWITCH_UNCHANGED:
+ break;
+ }
+ switch(s2) {
+ case DISEQC_SWITCH_A:
+ data[3] |= 0x20;
+ break;
+ case DISEQC_SWITCH_B:
+ data[3] |= 0x22;
+ break;
+ case DISEQC_SWITCH_UNCHANGED:
+ break;
+ }
+ switch(s3) {
+ case DISEQC_SWITCH_A:
+ data[3] |= 0x40;
+ break;
+ case DISEQC_SWITCH_B:
+ data[3] |= 0x44;
+ break;
+ case DISEQC_SWITCH_UNCHANGED:
+ break;
+ }
+ switch(s4) {
+ case DISEQC_SWITCH_A:
+ data[3] |= 0x80;
+ break;
+ case DISEQC_SWITCH_B:
+ data[3] |= 0x88;
+ break;
+ case DISEQC_SWITCH_UNCHANGED:
+ break;
+ }
+
+ if (data[3] == 0)
+ return 0;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_analog_value(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_analog_id id,
+ uint8_t value)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x48, value };
+
+ if (id == DISEQC_ANALOG_ID_A1)
+ data[2] = 0x49;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_frequency(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint32_t frequency)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x58, 0x00, 0x00, 0x00 };
+ int len = 5;
+
+ uint32_t bcdval = 0;
+ int i;
+ for(i=0; i<=24;i+=4) {
+ bcdval |= ((frequency % 10) << i);
+ frequency /= 10;
+ }
+
+ data[3] = bcdval >> 16;
+ data[4] = bcdval >> 8;
+ if (bcdval & 0xff) {
+ data[5] = bcdval;
+ len++;
+ }
+
+ return dvbfe_do_diseqc_command(fe, data, len);
+}
+
+int dvbsec_diseqc_set_channel(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint16_t channel)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x59, 0x00, 0x00};
+
+ data[3] = channel >> 8;
+ data[4] = channel;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_halt_satpos(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x60};
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_disable_satpos_limits(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x63};
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_set_satpos_limit(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_direction direction)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x66};
+
+ if (direction == DISEQC_DIRECTION_WEST)
+ data[2] = 0x67;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_drive_satpos_motor(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_direction direction,
+ enum dvbsec_diseqc_drive_mode mode,
+ uint8_t value)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x68, 0x00};
+
+ if (direction == DISEQC_DIRECTION_WEST)
+ data[2] = 0x69;
+
+ switch(mode) {
+ case DISEQC_DRIVE_MODE_STEPS:
+ data[3] = (value & 0x7f) | 0x80;
+ break;
+ case DISEQC_DRIVE_MODE_TIMEOUT:
+ data[3] = value & 0x7f;
+ break;
+ }
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_store_satpos_preset(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint8_t id)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x6A, id};
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_goto_satpos_preset(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint8_t id)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x6B, id};
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+int dvbsec_diseqc_recalculate_satpos_positions(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ int val1,
+ int val2)
+{
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x6F, 0x00, 0x00};
+ int len = 3;
+
+ if (val1 != -1) {
+ data[3] = val1;
+ len++;
+ }
+ if (val2 != -1) {
+ data[4] = val2;
+ len = 5;
+ }
+
+ return dvbfe_do_diseqc_command(fe, data, len);
+}
+
+int dvbsec_diseqc_goto_rotator_bearing(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ float angle)
+{
+ int integer = (int) angle;
+ uint8_t data[] = { DISEQC_FRAMING_MASTER_NOREPLY, address, 0x6e, 0x00, 0x00};
+
+ // transform the fraction into the correct representation
+ int fraction = (int) (((angle - integer) * 16.0) + 0.9) & 0x0f;
+ switch(fraction) {
+ case 1:
+ case 4:
+ case 7:
+ case 9:
+ case 12:
+ case 15:
+ fraction--;
+ break;
+ }
+
+ // generate the command
+ if (integer < -256) {
+ return -EINVAL;
+ } else if (integer < 0) {
+ integer = -integer;
+ data[3] = 0xf0;
+ } else if (integer < 256) {
+ data[3] = 0x00;
+ } else if (integer < 512) {
+ integer -= 256;
+ data[3] = 0x10;
+ } else {
+ return -EINVAL;
+ }
+ data[3] |= ((integer / 16) & 0x0f);
+ integer = integer % 16;
+ data[4] |= ((integer & 0x0f) << 4) | fraction;
+
+ return dvbfe_do_diseqc_command(fe, data, sizeof(data));
+}
+
+static int skipwhite(char **line, char *end)
+{
+ while(**line) {
+ if (end && (*line >= end))
+ return -1;
+ if (!isspace(**line))
+ return 0;
+ (*line)++;
+ }
+
+ return -1;
+}
+
+static int getstringupto(char **line, char *end, char *matches, char **ptrdest, int *ptrlen)
+{
+ char *start = *line;
+
+ while(**line) {
+ if (end && (*line >= end))
+ break;
+ if (strchr(matches, **line)) {
+ *ptrdest = start;
+ *ptrlen = *line - start;
+ return 0;
+ }
+ (*line)++;
+ }
+
+ *ptrdest = start;
+ *ptrlen = *line - start;
+ return 0;
+}
+
+static int parsefunction(char **line,
+ char **nameptr, int *namelen,
+ char **argsptr, int *argslen)
+{
+ if (skipwhite(line, NULL))
+ return -1;
+
+ if (getstringupto(line, NULL, "(", nameptr, namelen))
+ return -1;
+ if ((*line) == 0)
+ return -1;
+ (*line)++; // skip the '('
+ if (getstringupto(line, NULL, ")", argsptr, argslen))
+ return -1;
+ if ((*line) == 0)
+ return -1;
+ (*line)++; // skip the ')'
+
+ return 0;
+}
+
+static int parseintarg(char **args, char *argsend, int *result)
+{
+ char tmp[32];
+ char *arg;
+ int arglen;
+
+ // skip whitespace
+ if (skipwhite(args, argsend))
+ return -1;
+
+ // get the arg
+ if (getstringupto(args, argsend, ",", &arg, &arglen))
+ return -1;
+ if ((**args) == ',')
+ (*args)++; // skip the ',' if present
+ if (arglen > 31)
+ arglen = 31;
+ strncpy(tmp, arg, arglen);
+ tmp[arglen] = 0;
+
+ if (sscanf(tmp, "%i", result) != 1)
+ return -1;
+
+ return 0;
+}
+
+static int parsechararg(char **args, char *argsend, int *result)
+{
+ char *arg;
+ int arglen;
+
+ // skip whitespace
+ if (skipwhite(args, argsend))
+ return -1;
+
+ // get the arg
+ if (getstringupto(args, argsend, ",", &arg, &arglen))
+ return -1;
+ if ((**args) == ',')
+ (*args)++; // skip the ',' if present
+ if (arglen > 0)
+ *result = arg[0];
+
+ return 0;
+}
+
+static int parsefloatarg(char **args, char *argsend, float *result)
+{
+ char tmp[32];
+ char *arg;
+ int arglen;
+
+ // skip whitespace
+ if (skipwhite(args, argsend))
+ return -1;
+
+ // get the arg
+ if (getstringupto(args, argsend, ",", &arg, &arglen))
+ return -1;
+ if ((**args) == ',')
+ (*args)++; // skip the ',' if present
+ if (arglen > 31)
+ arglen = 31;
+ strncpy(tmp, arg, arglen);
+ arg[arglen] = 0;
+
+ if (sscanf(tmp, "%f", result) != 1)
+ return -1;
+
+ return 0;
+}
+
+static enum dvbsec_diseqc_switch parse_switch(int c)
+{
+ switch(toupper(c)) {
+ case 'A':
+ return DISEQC_SWITCH_A;
+ case 'B':
+ return DISEQC_SWITCH_B;
+ default:
+ return DISEQC_SWITCH_UNCHANGED;
+ }
+}
+
+int dvbsec_command(struct dvbfe_handle *fe, char *command)
+{
+ char *name;
+ char *args;
+ int namelen;
+ int argslen;
+ int address;
+ int iarg;
+ int iarg2;
+ int iarg3;
+ int iarg4;
+ float farg;
+
+ while(!parsefunction(&command, &name, &namelen, &args, &argslen)) {
+ char *argsend = args+argslen;
+
+ if (!strncasecmp(name, "tone", namelen)) {
+ if (parsechararg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("tone: %c\n", iarg);
+#else
+ if (toupper(iarg) == 'B') {
+ dvbfe_set_22k_tone(fe, DVBFE_SEC_TONE_ON);
+ } else {
+ dvbfe_set_22k_tone(fe, DVBFE_SEC_TONE_OFF);
+ }
+#endif
+ } else if (!strncasecmp(name, "voltage", namelen)) {
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("voltage: %i\n", iarg);
+#else
+ switch(iarg) {
+ case 0:
+ dvbfe_set_voltage(fe, DVBFE_SEC_VOLTAGE_OFF);
+ break;
+ case 13:
+ dvbfe_set_voltage(fe, DVBFE_SEC_VOLTAGE_13);
+ break;
+ case 18:
+ dvbfe_set_voltage(fe, DVBFE_SEC_VOLTAGE_18);
+ break;
+ default:
+ return -1;
+ }
+#endif
+ } else if (!strncasecmp(name, "toneburst", namelen)) {
+ if (parsechararg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("toneburst: %c\n", iarg);
+#else
+ if (toupper(iarg) == 'B') {
+ dvbfe_set_tone_data_burst(fe, DVBFE_SEC_MINI_B);
+ } else {
+ dvbfe_set_tone_data_burst(fe, DVBFE_SEC_MINI_A);
+ }
+#endif
+ } else if (!strncasecmp(name, "highvoltage", namelen)) {
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("highvoltage: %i\n", iarg);
+#else
+ dvbfe_set_high_lnb_voltage(fe, iarg ? 1 : 0);
+#endif
+ } else if (!strncasecmp(name, "dishnetworks", namelen)) {
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("dishnetworks: %i\n", iarg);
+#else
+ dvbfe_do_dishnetworks_legacy_command(fe, iarg);
+#endif
+ } else if (!strncasecmp(name, "wait", namelen)) {
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("wait: %i\n", iarg);
+#else
+ if (iarg)
+ usleep(iarg * 1000);
+#endif
+ } else if (!strncasecmp(name, "Dreset", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dreset: %i %i\n", address, iarg);
+#else
+ if (iarg) {
+ dvbsec_diseqc_set_reset(fe, address, DISEQC_RESET);
+ } else {
+ dvbsec_diseqc_set_reset(fe, address, DISEQC_RESET_CLEAR);
+ }
+#endif
+ } else if (!strncasecmp(name, "Dpower", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dpower: %i %i\n", address, iarg);
+#else
+ if (iarg) {
+ dvbsec_diseqc_set_power(fe, address, DISEQC_POWER_ON);
+ } else {
+ dvbsec_diseqc_set_power(fe, address, DISEQC_POWER_OFF);
+ }
+#endif
+ } else if (!strncasecmp(name, "Dcommitted", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg2))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg3))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg4))
+ return -1;
+
+ enum dvbsec_diseqc_oscillator oscillator;
+ switch(toupper(iarg)) {
+ case 'H':
+ oscillator = DISEQC_OSCILLATOR_HIGH;
+ break;
+ case 'L':
+ oscillator = DISEQC_OSCILLATOR_LOW;
+ break;
+ default:
+ oscillator = DISEQC_OSCILLATOR_UNCHANGED;
+ break;
+ }
+
+ int polarization = -1;
+ switch(toupper(iarg2)) {
+ case 'H':
+ polarization = DISEQC_POLARIZATION_H;
+ break;
+ case 'V':
+ polarization = DISEQC_POLARIZATION_V;
+ break;
+ case 'L':
+ polarization = DISEQC_POLARIZATION_L;
+ break;
+ case 'R':
+ polarization = DISEQC_POLARIZATION_R;
+ break;
+ default:
+ polarization = -1;
+ break;
+ }
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dcommitted: %i %i %i %i %i\n", address,
+ oscillator,
+ polarization,
+ parse_switch(iarg3),
+ parse_switch(iarg4));
+#else
+ dvbsec_diseqc_set_committed_switches(fe, address,
+ oscillator,
+ polarization,
+ parse_switch(iarg3),
+ parse_switch(iarg4));
+#endif
+ } else if (!strncasecmp(name, "Duncommitted", namelen)) {
+ if (parsechararg(&args, argsend, &address))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg2))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg3))
+ return -1;
+ if (parsechararg(&args, argsend, &iarg4))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Duncommitted: %i %i %i %i %i\n", address,
+ parse_switch(iarg),
+ parse_switch(iarg2),
+ parse_switch(iarg3),
+ parse_switch(iarg4));
+#else
+ dvbsec_diseqc_set_uncommitted_switches(fe, address,
+ parse_switch(iarg),
+ parse_switch(iarg2),
+ parse_switch(iarg3),
+ parse_switch(iarg4));
+#endif
+ } else if (!strncasecmp(name, "Dfrequency", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dfrequency: %i %i\n", address, iarg);
+#else
+ dvbsec_diseqc_set_frequency(fe, address, iarg);
+#endif
+ } else if (!strncasecmp(name, "Dchannel", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dchannel: %i %i\n", address, iarg);
+#else
+ dvbsec_diseqc_set_channel(fe, address, iarg);
+#endif
+ } else if (!strncasecmp(name, "Dgotopreset", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parseintarg(&args, argsend, &iarg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dgotopreset: %i %i\n", address, iarg);
+#else
+ dvbsec_diseqc_goto_satpos_preset(fe, address, iarg);
+#endif
+ } else if (!strncasecmp(name, "Dgotobearing", namelen)) {
+ if (parseintarg(&args, argsend, &address))
+ return -1;
+ if (parsefloatarg(&args, argsend, &farg))
+ return -1;
+
+#ifdef TEST_SEC_COMMAND
+ printf("Dgotobearing: %i %f\n", address, farg);
+#else
+ dvbsec_diseqc_goto_rotator_bearing(fe, address, farg);
+#endif
+ } else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/lib/libdvbsec/dvbsec_api.h b/lib/libdvbsec/dvbsec_api.h
new file mode 100644
index 0000000..7e454d7
--- /dev/null
+++ b/lib/libdvbsec/dvbsec_api.h
@@ -0,0 +1,436 @@
+/*
+ libdvbsec - an SEC library
+
+ Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef DVBSEC_API_H
+#define DVBSEC_API_H 1
+
+#include <stdint.h>
+
+struct dvbfe_handle;
+struct dvbfe_parameters;
+
+enum dvbsec_diseqc_framing {
+ DISEQC_FRAMING_MASTER_NOREPLY = 0xE0,
+ DISEQC_FRAMING_MASTER_NOREPLY_REPEAT = 0xE1,
+ DISEQC_FRAMING_MASTER_REPLY = 0xE2,
+ DISEQC_FRAMING_MASTER_REPLY_REPEAT = 0xE3,
+ DISEQC_FRAMING_SLAVE_OK = 0xE4,
+ DISEQC_FRAMING_SLAVE_UNSUPPORTED = 0xE5,
+ DISEQC_FRAMING_SLAVE_PARITY_ERROR = 0xE6,
+ DISEQC_FRAMING_SLAVE_UNRECOGNISED = 0xE7,
+};
+
+enum dvbsec_diseqc_address {
+ DISEQC_ADDRESS_ANY_DEVICE = 0x00,
+
+ DISEQC_ADDRESS_ANY_LNB_SWITCHER_SMATV = 0x10,
+ DISEQC_ADDRESS_LNB = 0x11,
+ DISEQC_ADDRESS_LNB_WITH_LOOP = 0x12,
+ DISEQC_ADDRESS_SWITCHER = 0x14,
+ DISEQC_ADDRESS_SWITCHER_WITH_LOOP = 0x15,
+ DISEQC_ADDRESS_SMATV = 0x18,
+
+ DISEQC_ADDRESS_ANY_POLARISER = 0x20,
+ DISEQC_ADDRESS_LINEAR_POLARISER = 0x21,
+
+ DISEQC_ADDRESS_ANY_POSITIONER = 0x30,
+ DISEQC_ADDRESS_POLAR_AZIMUTH_POSITIONER = 0x31,
+ DISEQC_ADDRESS_ELEVATION_POSITIONER = 0x32,
+
+ DISEQC_ADDRESS_ANY_INSTALLER_AID = 0x40,
+ DISEQC_ADDRESS_SIGNAL_STRENGTH = 0x41,
+
+ DISEQC_ADDRESS_ANY_INTERFACE = 0x70,
+ DISEQC_ADDRESS_HEADEND_INTERFACE = 0x71,
+
+ DISEQC_ADDRESS_REALLOC_BASE = 0x60,
+ DISEQC_ADDRESS_OEM_BASE = 0xf0,
+};
+
+enum dvbsec_diseqc_reset {
+ DISEQC_RESET,
+ DISEQC_RESET_CLEAR,
+};
+
+enum dvbsec_diseqc_power {
+ DISEQC_POWER_OFF,
+ DISEQC_POWER_ON,
+};
+
+enum dvbsec_diseqc_listen {
+ DISEQC_LISTEN_SLEEP,
+ DISEQC_LISTEN_AWAKE,
+};
+
+enum dvbsec_diseqc_polarization {
+ DISEQC_POLARIZATION_UNCHANGED = 0,
+ DISEQC_POLARIZATION_H = 'h',
+ DISEQC_POLARIZATION_V = 'v',
+ DISEQC_POLARIZATION_L = 'l',
+ DISEQC_POLARIZATION_R = 'r',
+};
+
+enum dvbsec_diseqc_oscillator {
+ DISEQC_OSCILLATOR_UNCHANGED = 0,
+ DISEQC_OSCILLATOR_LOW,
+ DISEQC_OSCILLATOR_HIGH,
+};
+
+enum dvbsec_diseqc_switch {
+ DISEQC_SWITCH_UNCHANGED = 0,
+ DISEQC_SWITCH_A,
+ DISEQC_SWITCH_B,
+};
+
+enum dvbsec_diseqc_analog_id {
+ DISEQC_ANALOG_ID_A0,
+ DISEQC_ANALOG_ID_A1,
+};
+
+enum dvbsec_diseqc_drive_mode {
+ DISEQC_DRIVE_MODE_STEPS,
+ DISEQC_DRIVE_MODE_TIMEOUT,
+};
+
+enum dvbsec_diseqc_direction {
+ DISEQC_DIRECTION_EAST,
+ DISEQC_DIRECTION_WEST,
+};
+
+enum dvbsec_config_type {
+ DVBSEC_CONFIG_NONE = 0,
+ DVBSEC_CONFIG_POWER,
+ DVBSEC_CONFIG_STANDARD,
+ DVBSEC_CONFIG_ADVANCED,
+};
+
+
+#define MAX_SEC_CMD_LEN 100
+
+struct dvbsec_config
+{
+ char id[32]; /* ID of this SEC config structure */
+ uint32_t switch_frequency; /* switching frequency - supply 0 for none. */
+ uint32_t lof_lo_v; /* frequency to subtract for V + LOW band channels - or for switch_frequency == 0 */
+ uint32_t lof_lo_h; /* frequency to subtract for H + LOW band channels - or for switch_frequency == 0 */
+ uint32_t lof_lo_l; /* frequency to subtract for L + LOW band channels - or for switch_frequency == 0 */
+ uint32_t lof_lo_r; /* frequency to subtract for R + LOW band channels - or for switch_frequency == 0 */
+ uint32_t lof_hi_v; /* frequency to subtract for V + HIGH band channels */
+ uint32_t lof_hi_h; /* frequency to subtract for H + HIGH band channels */
+ uint32_t lof_hi_l; /* frequency to subtract for L + HIGH band channels */
+ uint32_t lof_hi_r; /* frequency to subtract for R + HIGH band channels */
+
+ /**
+ * The SEC control to be used depends on the type:
+ *
+ * NONE - no SEC commands will be issued. (Frequency adjustment will still be performed).
+ *
+ * POWER - only the SEC power will be turned on.
+ *
+ * STANDARD - the standard DISEQC back compatable sequence is used.
+ *
+ * ADVANCED - SEC strings are supplied by the user describing the exact sequence
+ * of operations to use.
+ */
+ enum dvbsec_config_type config_type;
+
+ /* stuff for type == dvbsec_config_ADVANCED */
+ char adv_cmd_lo_h[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for LOW/H. */
+ char adv_cmd_lo_v[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for LOW/V. */
+ char adv_cmd_lo_l[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for LOW/L. */
+ char adv_cmd_lo_r[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for LOW/R. */
+ char adv_cmd_hi_h[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for HI/H. */
+ char adv_cmd_hi_v[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for HI/V. */
+ char adv_cmd_hi_l[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for HI/L. */
+ char adv_cmd_hi_r[MAX_SEC_CMD_LEN]; /* ADVANCED SEC command to use for HI/R. */
+};
+
+/**
+ * Helper function for tuning adapters with SEC support. This function will do
+ * everything required, including frequency adjustment based on the parameters
+ * in sec_config.
+ *
+ * Note: Since the SEC configuration structure can be set to disable any SEC
+ * operations, this function can be reused for ALL DVB style devices (just
+ * set all LOF=0,type=dvbsec_config_NONE for devices which do not require
+ * SEC control).
+ *
+ * The sec configuration structures can be looked up using the dvbcfg_sec library.
+ *
+ * @param fe Frontend concerned.
+ * @param sec_config SEC configuration structure. May be NULL to disable SEC/frequency adjustment.
+ * @param polarization Polarization of signal.
+ * @param sat_pos Satellite position - only used if type == DISEQC_SEC_CONFIG_STANDARD.
+ * @param switch_option Switch option - only used if type == DISEQC_SEC_CONFIG_STANDARD.
+ * @param params Tuning parameters.
+ * @param timeout <0 => wait forever for lock. 0=>return immediately, >0=>
+ * number of milliseconds to wait for a lock.
+ * @return 0 on locked (or if timeout==0 and everything else worked), or
+ * nonzero on failure (including no lock).
+ */
+extern int dvbsec_set(struct dvbfe_handle *fe,
+ struct dvbsec_config *sec_config,
+ enum dvbsec_diseqc_polarization polarization,
+ enum dvbsec_diseqc_switch sat_pos,
+ enum dvbsec_diseqc_switch switch_option,
+ struct dvbfe_parameters *params,
+ int timeout);
+
+/**
+ * This will issue the standardised back-compatable DISEQC/SEC command
+ * sequence as defined in the DISEQC spec:
+ *
+ * i.e. tone off, set voltage, wait15, DISEQC, wait15, toneburst, wait15, set tone.
+ *
+ * @param fe Frontend concerned.
+ * @param oscillator Value to set the lo/hi switch to.
+ * @param polarization Value to set the polarisation switch to.
+ * @param sat_pos Value to set the satellite position switch to.
+ * @param switch_option Value to set the "swtch option" switch to.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_std_sequence(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_oscillator oscillator,
+ enum dvbsec_diseqc_polarization polarization,
+ enum dvbsec_diseqc_switch sat_pos,
+ enum dvbsec_diseqc_switch switch_option);
+
+/**
+ * Execute an SEC command string on the provided frontend. Please see the documentation
+ * in dvbsec_cfg.h on the command format,
+ *
+ * @param fe Frontend concerned.
+ * @param command The command to execute.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_command(struct dvbfe_handle *fe, char *command);
+
+/**
+ * Control the reset status of an attached DISEQC device.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param state The state to set.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_reset(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_reset state);
+
+/**
+ * Control the power status of an attached DISEQC peripheral.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param state The state to set.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_power(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_power state);
+
+/**
+ * Control the listening status of an attached DISEQC peripheral.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param state The state to set.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_listen(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_listen state);
+
+/**
+ * Set the state of the committed switches of a DISEQC device.
+ * These are switches which are defined to have a standard name.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param oscillator Value to set the lo/hi switch to.
+ * @param polarization Value to set the polarization switch to.
+ * @param sat_pos Value to set the satellite position switch to.
+ * @param switch_option Value to set the switch option switch to.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_committed_switches(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_oscillator oscillator,
+ enum dvbsec_diseqc_polarization polarization,
+ enum dvbsec_diseqc_switch sat_pos,
+ enum dvbsec_diseqc_switch switch_option);
+
+/**
+ * Set the state of the uncommitted switches of a DISEQC device.
+ * These provide another four switching possibilities.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param s1 Value to set the S1 switch to.
+ * @param s2 Value to set the S2 switch to.
+ * @param s3 Value to set the S3 switch to.
+ * @param s3 Value to set the S4 switch to.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_uncommitted_switches(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_switch s1,
+ enum dvbsec_diseqc_switch s2,
+ enum dvbsec_diseqc_switch s3,
+ enum dvbsec_diseqc_switch s4);
+
+/**
+ * Set an analogue value.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param id The id of the analogue value to set.
+ * @param value The value to set.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_analog_value(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_analog_id id,
+ uint8_t value);
+
+/**
+ * Set the desired frequency.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param frequency The frequency to set in GHz.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_frequency(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint32_t frequency);
+
+/**
+ * Set the desired channel.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param channel ID of the channel to set.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_channel(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint16_t channel);
+
+/**
+ * Halt the satellite positioner.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_halt_satpos(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address);
+
+/**
+ * Disable satellite positioner limits.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_disable_satpos_limits(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address);
+
+/**
+ * Set satellite positioner limits.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_set_satpos_limit(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_direction direction);
+
+/**
+ * Drive satellite positioner motor.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param direction Direction to drive in.
+ * @param mode Drive mode to use
+ * (TIMEOUT=>value is a timeout in seconds, or STEPS=>value is a count of steps to use)
+ * @param value Value associated with the drive mode (range 0->127)
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_drive_satpos_motor(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ enum dvbsec_diseqc_direction direction,
+ enum dvbsec_diseqc_drive_mode mode,
+ uint8_t value);
+
+/**
+ * Store satellite positioner preset id at current position.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param id ID of the preset.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_store_satpos_preset(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint8_t id);
+
+/**
+ * Send a satellite positioner to a pre-set position.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param id ID of the preset.
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_goto_satpos_preset(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ uint8_t id);
+
+/**
+ * Recalculate satellite positions based on the current position, using
+ * magic positioner specific values.
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param val1 value1 (range 0->255, pass -1 to ignore).
+ * @param val2 value2 (range 0->255, pass -1 to ignore).
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_recalculate_satpos_positions(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ int val1,
+ int val2);
+
+/**
+ * Send a terrestrial aerial rotator to a particular bearing
+ * (0 degrees = north, fractional angles allowed).
+ *
+ * @param fe Frontend concerned.
+ * @param address Address of the device.
+ * @param angle Angle to rotate to (-256.0 -> 512.0)
+ * @return 0 on success, or nonzero on error.
+ */
+extern int dvbsec_diseqc_goto_rotator_bearing(struct dvbfe_handle *fe,
+ enum dvbsec_diseqc_address address,
+ float angle);
+
+#endif
diff --git a/lib/libdvbsec/dvbsec_cfg.c b/lib/libdvbsec/dvbsec_cfg.c
new file mode 100644
index 0000000..4b05a32
--- /dev/null
+++ b/lib/libdvbsec/dvbsec_cfg.c
@@ -0,0 +1,366 @@
+/**
+ * dvbsec_cfg (i.e. linuxtv sec format) configuration file support.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <linux/types.h>
+#include "dvbsec_cfg.h"
+
+int dvbcfg_issection(char* line, char* sectionname)
+{
+ int len;
+
+ len = strlen(line);
+ if (len < 2)
+ return 0;
+
+ if ((line[0] != '[') || (line[len-1] != ']'))
+ return 0;
+
+ line++;
+ while(isspace(*line))
+ line++;
+
+ if (strncmp(line, sectionname, strlen(sectionname)))
+ return 0;
+
+ return 1;
+}
+
+char* dvbcfg_iskey(char* line, char* keyname)
+{
+ int len = strlen(keyname);
+
+ /* does the key match? */
+ if (strncmp(line, keyname, len))
+ return NULL;
+
+ /* skip keyname & any whitespace */
+ line += len;
+ while(isspace(*line))
+ line++;
+
+ /* should be the '=' sign */
+ if (*line != '=')
+ return 0;
+
+ /* more whitespace skipping */
+ line++;
+ while(isspace(*line))
+ line++;
+
+ /* finally, return the value */
+ return line;
+}
+
+int dvbsec_cfg_load(FILE *f,
+ void *arg,
+ dvbsec_cfg_callback cb)
+{
+ struct dvbsec_config tmpsec;
+ char *linebuf = NULL;
+ size_t line_size = 0;
+ int len;
+ int insection = 0;
+ char *value;
+
+ /* process each line */
+ while((len = getline(&linebuf, &line_size, f)) > 0) {
+ char *line = linebuf;
+
+ /* chop any comments */
+ char *hashpos = strchr(line, '#');
+ if (hashpos)
+ *hashpos = 0;
+ char *lineend = line + strlen(line);
+
+ /* trim the line */
+ while(*line && isspace(*line))
+ line++;
+ while((lineend != line) && isspace(*(lineend-1)))
+ lineend--;
+ *lineend = 0;
+
+ /* skip blank lines */
+ if (*line == 0)
+ continue;
+
+ if (dvbcfg_issection(line, "sec")) {
+ if (insection) {
+ if (cb(arg, &tmpsec))
+ return 0;
+ }
+ insection = 1;
+ memset(&tmpsec, 0, sizeof(tmpsec));
+
+ } else if ((value = dvbcfg_iskey(line, "name")) != NULL) {
+ strncpy(tmpsec.id, value, sizeof(tmpsec.id));
+ } else if ((value = dvbcfg_iskey(line, "switch-frequency")) != NULL) {
+ tmpsec.switch_frequency = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-lo-v")) != NULL) {
+ tmpsec.lof_lo_v = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-lo-h")) != NULL) {
+ tmpsec.lof_lo_h = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-lo-l")) != NULL) {
+ tmpsec.lof_lo_l = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-lo-r")) != NULL) {
+ tmpsec.lof_lo_r = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-hi-v")) != NULL) {
+ tmpsec.lof_hi_v = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-hi-h")) != NULL) {
+ tmpsec.lof_hi_h = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-hi-l")) != NULL) {
+ tmpsec.lof_hi_l = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "lof-hi-r")) != NULL) {
+ tmpsec.lof_hi_r = atoi(value);
+ } else if ((value = dvbcfg_iskey(line, "config-type")) != NULL) {
+ if (!strcasecmp(value, "none")) {
+ tmpsec.config_type = DVBSEC_CONFIG_NONE;
+ } else if (!strcasecmp(value, "power")) {
+ tmpsec.config_type = DVBSEC_CONFIG_POWER;
+ } else if (!strcasecmp(value, "standard")) {
+ tmpsec.config_type = DVBSEC_CONFIG_STANDARD;
+ } else if (!strcasecmp(value, "advanced")) {
+ tmpsec.config_type = DVBSEC_CONFIG_ADVANCED;
+ } else {
+ insection = 0;
+ }
+ } else if ((value = dvbcfg_iskey(line, "cmd-lo-v")) != NULL) {
+ strncpy(tmpsec.adv_cmd_lo_v, value, sizeof(tmpsec.adv_cmd_lo_v));
+ } else if ((value = dvbcfg_iskey(line, "cmd-lo-h")) != NULL) {
+ strncpy(tmpsec.adv_cmd_lo_h, value, sizeof(tmpsec.adv_cmd_lo_h));
+ } else if ((value = dvbcfg_iskey(line, "cmd-lo-r")) != NULL) {
+ strncpy(tmpsec.adv_cmd_lo_r, value, sizeof(tmpsec.adv_cmd_lo_r));
+ } else if ((value = dvbcfg_iskey(line, "cmd-lo-l")) != NULL) {
+ strncpy(tmpsec.adv_cmd_lo_l, value, sizeof(tmpsec.adv_cmd_lo_l));
+ } else if ((value = dvbcfg_iskey(line, "cmd-hi-v")) != NULL) {
+ strncpy(tmpsec.adv_cmd_hi_v, value, sizeof(tmpsec.adv_cmd_hi_v));
+ } else if ((value = dvbcfg_iskey(line, "cmd-hi-h")) != NULL) {
+ strncpy(tmpsec.adv_cmd_hi_h, value, sizeof(tmpsec.adv_cmd_hi_h));
+ } else if ((value = dvbcfg_iskey(line, "cmd-hi-r")) != NULL) {
+ strncpy(tmpsec.adv_cmd_hi_r, value, sizeof(tmpsec.adv_cmd_hi_r));
+ } else if ((value = dvbcfg_iskey(line, "cmd-hi-l")) != NULL) {
+ strncpy(tmpsec.adv_cmd_hi_l, value, sizeof(tmpsec.adv_cmd_hi_l));
+ } else {
+ insection = 0;
+ }
+ }
+
+ // output the final section if there is one
+ if (insection) {
+ if (cb(arg, &tmpsec))
+ return 0;
+ }
+
+ if (linebuf)
+ free(linebuf);
+ return 0;
+}
+
+static int dvbsec_cfg_find_callback(void *arg, struct dvbsec_config *sec);
+static int dvbsec_cfg_find_default(const char *sec_id, struct dvbsec_config *sec);
+
+struct findparams {
+ const char *sec_id;
+ struct dvbsec_config *sec_dest;
+};
+
+int dvbsec_cfg_find(const char *config_file,
+ const char *sec_id,
+ struct dvbsec_config *sec)
+{
+ struct findparams findp;
+
+ // clear the structure
+ memset(sec, 0, sizeof(struct dvbsec_config));
+
+ // open the file
+ if (config_file != NULL) {
+ FILE *f = fopen(config_file, "r");
+ if (f == NULL)
+ return -EIO;
+
+ // parse each entry
+ findp.sec_id = sec_id;
+ findp.sec_dest = sec;
+ dvbsec_cfg_load(f, &findp, dvbsec_cfg_find_callback);
+
+ // done
+ fclose(f);
+
+ // find it?
+ if (sec->id[0])
+ return 0;
+ }
+
+ return dvbsec_cfg_find_default(sec_id, sec);
+}
+
+static int dvbsec_cfg_find_callback(void *arg, struct dvbsec_config *sec)
+{
+ struct findparams *findp = arg;
+
+ if (strcmp(findp->sec_id, sec->id))
+ return 0;
+
+ memcpy(findp->sec_dest, sec, sizeof(struct dvbsec_config));
+ return 1;
+}
+
+int dvbsec_cfg_save(FILE *f,
+ struct dvbsec_config *secs,
+ int count)
+{
+ int i;
+
+ for(i=0; i<count; i++) {
+ char *config_type = "";
+ switch(secs[i].config_type) {
+ case DVBSEC_CONFIG_NONE:
+ config_type = "none";
+ break;
+ case DVBSEC_CONFIG_POWER:
+ config_type = "power";
+ break;
+ case DVBSEC_CONFIG_STANDARD:
+ config_type = "standard";
+ break;
+ case DVBSEC_CONFIG_ADVANCED:
+ config_type = "advanced";
+ break;
+ }
+
+ fprintf(f, "[lnb]\n");
+ fprintf(f, "switch-frequency=%i\n", secs[i].switch_frequency);
+ if (secs[i].lof_lo_v)
+ fprintf(f, "lof-lo-v=%i\n", secs[i].lof_lo_v);
+ if (secs[i].lof_lo_h)
+ fprintf(f, "lof-lo-h=%i\n", secs[i].lof_lo_h);
+ if (secs[i].lof_lo_l)
+ fprintf(f, "lof-lo-l=%i\n", secs[i].lof_lo_l);
+ if (secs[i].lof_lo_r)
+ fprintf(f, "lof-lo-r=%i\n", secs[i].lof_lo_r);
+ if (secs[i].lof_hi_v)
+ fprintf(f, "lof-hi-v=%i\n", secs[i].lof_hi_v);
+ if (secs[i].lof_hi_h)
+ fprintf(f, "lof-hi-h=%i\n", secs[i].lof_hi_h);
+ if (secs[i].lof_hi_l)
+ fprintf(f, "lof-hi-l=%i\n", secs[i].lof_hi_l);
+ if (secs[i].lof_hi_r)
+ fprintf(f, "lof-hi-r=%i\n", secs[i].lof_hi_r);
+ fprintf(f, "config-type=%s\n", config_type);
+
+ if (secs[i].config_type == DVBSEC_CONFIG_ADVANCED) {
+ if (secs[i].adv_cmd_lo_h[0])
+ fprintf(f, "cmd-lo-h=%s\n", secs[i].adv_cmd_lo_h);
+ if (secs[i].adv_cmd_lo_v[0])
+ fprintf(f, "cmd-lo-v=%s\n", secs[i].adv_cmd_lo_v);
+ if (secs[i].adv_cmd_lo_r[0])
+ fprintf(f, "cmd-lo-r=%s\n", secs[i].adv_cmd_lo_r);
+ if (secs[i].adv_cmd_lo_l[0])
+ fprintf(f, "cmd-lo-l=%s\n", secs[i].adv_cmd_lo_l);
+ if (secs[i].adv_cmd_hi_h[0])
+ fprintf(f, "cmd-hi-h=%s\n", secs[i].adv_cmd_hi_h);
+ if (secs[i].adv_cmd_hi_v[0])
+ fprintf(f, "cmd-hi-v=%s\n", secs[i].adv_cmd_hi_v);
+ if (secs[i].adv_cmd_hi_r[0])
+ fprintf(f, "cmd-hi-r=%s\n", secs[i].adv_cmd_hi_r);
+ if (secs[i].adv_cmd_hi_l[0])
+ fprintf(f, "cmd-hi-l=%s\n", secs[i].adv_cmd_hi_l);
+ }
+
+ fprintf(f, "\n");
+ }
+
+ return 0;
+}
+
+static struct dvbsec_config defaults[] = {
+
+ {
+ .id = "NULL",
+ .config_type = DVBSEC_CONFIG_STANDARD,
+ },
+ {
+ .id = "UNIVERSAL",
+ .switch_frequency = 11700000,
+ .lof_lo_v = 9750000,
+ .lof_lo_h = 9750000,
+ .lof_hi_v = 10600000,
+ .lof_hi_h = 10600000,
+ .config_type = DVBSEC_CONFIG_STANDARD,
+ },
+ {
+ .id = "DBS",
+ .switch_frequency = 0,
+ .lof_lo_v = 11250000,
+ .lof_lo_h = 11250000,
+ .config_type = DVBSEC_CONFIG_STANDARD,
+ },
+ {
+ .id = "STANDARD",
+ .switch_frequency = 0,
+ .lof_lo_v = 10000000,
+ .lof_lo_h = 10000000,
+ .config_type = DVBSEC_CONFIG_STANDARD,
+ },
+ {
+ .id = "ENHANCED",
+ .switch_frequency = 0,
+ .lof_lo_v = 9750000,
+ .lof_lo_h = 9750000,
+ .config_type = DVBSEC_CONFIG_STANDARD,
+ },
+ {
+ .id = "C-BAND",
+ .switch_frequency = 0,
+ .lof_lo_v = 5150000,
+ .lof_lo_h = 5150000,
+ .config_type = DVBSEC_CONFIG_POWER,
+ },
+ {
+ .id = "C-MULTI",
+ .switch_frequency = 0,
+ .lof_lo_v = 5150000,
+ .lof_lo_h = 5750000,
+ .config_type = DVBSEC_CONFIG_POWER,
+ },
+};
+#define defaults_count (sizeof(defaults) / sizeof(struct dvbsec_config))
+
+static int dvbsec_cfg_find_default(const char *sec_id,
+ struct dvbsec_config *sec)
+{
+ unsigned int i;
+
+ for(i=0; i< defaults_count; i++) {
+ if (!strncmp(sec_id, defaults[i].id, sizeof(defaults[i].id))) {
+ memcpy(sec, &defaults[i], sizeof(struct dvbsec_config));
+ return 0;
+ }
+ }
+
+ return -1;
+}
diff --git a/lib/libdvbsec/dvbsec_cfg.h b/lib/libdvbsec/dvbsec_cfg.h
new file mode 100644
index 0000000..d4546de
--- /dev/null
+++ b/lib/libdvbsec/dvbsec_cfg.h
@@ -0,0 +1,203 @@
+/**
+ * dvbsec_cfg (i.e. linuxtv SEC format) configuration file support.
+ *
+ * Copyright (c) 2006 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * This library allows SEC (Satellite Equipment Control) configurations
+ * to be retrieved. Each configuration is identified by a unique satellite_id.
+ *
+ * In order to make things as easy as possible for users, there are a set of
+ * defaults hardcoded into the library covering the majority of LNB types. When
+ * these are used, the standard back-compatable sequence defined in the DISEQC
+ * standard will be used - this will suffice for _most_ situations.
+ *
+ * UNIVERSAL - Europe, 10800 to 11800 MHz and 11600 to 12700 Mhz, Dual LO, loband 9750, hiband 10600 MHz.
+ * DBS - Expressvu, North America, 12200 to 12700 MHz, Single LO, 11250 MHz.
+ * STANDARD - 10945 to 11450 Mhz, Single LO, 10000Mhz.
+ * ENHANCED - Astra, 10700 to 11700 MHz, Single LO, 9750MHz.
+ * C-BAND - Big Dish, 3700 to 4200 MHz, Single LO, 5150Mhz.
+ * C-MULTI - Big Dish - Multipoint LNBf, 3700 to 4200 MHz, Dual LO, H:5150MHz, V:5750MHz.
+ *
+ * However, for the power user with a more complex setup, these simple defaults
+ * are not enough. Therefore, it is also possible to define additional SEC
+ * configurations in an external configuration file. This file consists of multiple
+ * entries in the following format:
+ *
+ * [sec]
+ * name=<sec_id>
+ * switch-frequency=<switching frequency (SLOF)>
+ * lof-lo-v=<low band + V + frequency>
+ * lof-lo-h=<low band + H + frequency>
+ * lof-lo-l=<low band + L + frequency>
+ * lof-lo-r=<low band + R + frequency>
+ * lof-hi-v=<high band + V + frequency>
+ * lof-hi-h=<high band + H + frequency>
+ * lof-hi-l=<high band + L + frequency>
+ * lof-hi-r=<high band + R + frequency>
+ * config-type=<none|power|standard|advanced>
+ * cmd-lo-v=<sec sequence>
+ * cmd-lo-h=<sec sequence>
+ * cmd-lo-r=<sec sequence>
+ * cmd-lo-l=<sec sequence>
+ * cmd-hi-v=<sec sequence>
+ * cmd-hi-h=<sec sequence>
+ * cmd-hi-r=<sec sequence>
+ * cmd-hi-l=<sec sequence>
+ *
+ * The sec_id is whatever unique value you wish. If it is the same as one of the hardcoded defaults, the configuration
+ * details from the file will be used instead of the hardcoded ones.
+ * The switch-frequency (or SLOF) indicates the point seperating low band frequencies from high band frequencies.
+ * Set this value to 0 if there is only one frequency band.
+ * The lof-lo-v is the frequency adjustment for V + low band (i.e. less than SLOF), or is used if switch-frequency==0.
+ * The lof-lo-h is the frequency adjustment for H + low band (i.e. less than SLOF), or is used if switch-frequency==0.
+ * The lof-lo-l is the frequency adjustment for L + low band (i.e. less than SLOF), or is used if switch-frequency==0.
+ * The lof-lo-r is the frequency adjustment for R + low band (i.e. less than SLOF), or is used if switch-frequency==0.
+ * The lof-hi-v is the frequency adjustment for V + high band (unused if switch-frequency==0).
+ * The lof-hi-h is the frequency adjustment for H + high band (unused if switch-frequency==0).
+ * The lof-hi-l is the frequency adjustment for L + high band (unused if switch-frequency==0).
+ * The lof-hi-r is the frequency adjustment for R + high band (unused if switch-frequency==0).
+ *
+ * config-type indicates the desired type of SEC command to use, it may be:
+ * none - No SEC commands will be issued (frequency adjustment will still be performed).
+ * power - Only the SEC power is turned on.
+ * standard - The standard DISEQC back compatable sequence will be issued.
+ * advanced - The DISEQC sequence described in the appropriate sec cmd string will be used.
+ *
+ * The cmd-<lo|hi>-<v|h|l|r> describes the SEC cmd string to use in advanced mode for each of the possible combinations of
+ * frequency band and polarisation. If a certain combination is not required, it may be omitted. It consists of a
+ * space seperated combination of commands - those available are as follows:
+ *
+ * tone(<0|1>) - control the 22kHz tone 0:off, 1:on
+ * voltage(<0|13|18>) - control the LNB voltage 0v, 13v, or 18v
+ * toneburst(<a|b>) - issue a toneburst (mini command) for position A or B.
+ * highvoltage(<0|1>) - control high lnb voltage for long cable runs 0: normal, 1:add 1v to LNB voltage.
+ * dishnetworks(<integer>) - issue a dishnetworks legacy command.
+ * wait(<integer>) - wait for the given number of milliseconds.
+ * Dreset(<address>, <0|1>) - control the reset state of a DISEC device, 0:disable reset, 1:enable reset.
+ * Dpower(<address>, <0|1>) - control the power of a DISEC device, 0:off, 1:on.
+ * Dcommitted(<address>, <h|l|x>, <v|h|l|r|x>, <a|b|x>, <a|b|x>) - Write to the committed switches of a DISEC device.
+ * The parameters are for band, polarisation, satelliteposition, switchoption:
+ * band - h:high band, l:low band
+ * polarisation - v: vertical, h:horizontal,r:right,l:left
+ * satelliteposition - a:position A, b: position B
+ * switchoption - a:position A, b: position B
+ * The special value 'x' means "no change to this switch".
+ *
+ * Duncommitted(<address>, <a|b|x>, <a|b|x>, <a|b|x>, <a|b|x>) - Write to the uncommitted switches of the a DISEC device.
+ * The parameters are for switch1, switch2, switch3, switch4, and may be set to position a or b.
+ * The special value 'x' means "no change to this switch".
+ *
+ * Dfrequency(<address>, <frequency in GHz>) - set the frequency of a DISEC device.
+ * Dchannel(<address>, <channel id>) - set the desired channel id of a DISEC device.
+ * Dgotopreset(<address>, <preset id>) - tell a DISEC satellite positioner to move to the given preset id.
+ * Dgotobearing(<address>, <bearing in degrees>) - tell a DISEQC terrestrial rotator to go to the
+ * given bearing (range -256.0 -> 512.0 degrees, fractions allowed).
+ *
+ * In the above DISEQC commands, <address> is the integer (normally in hex format) address of the
+ * diseqc device to communicate with. A list of possiblities is as follows:
+ *
+ * DISEQC_ADDRESS_ANY_DEVICE = 0x00
+ *
+ * DISEQC_ADDRESS_ANY_LNB_SWITCHER_SMATV = 0x10
+ * DISEQC_ADDRESS_LNB = 0x11
+ * DISEQC_ADDRESS_LNB_WITH_LOOP = 0x12
+ * DISEQC_ADDRESS_SWITCHER = 0x14
+ * DISEQC_ADDRESS_SWITCHER_WITH_LOOP = 0x15
+ * DISEQC_ADDRESS_SMATV = 0x18
+ *
+ * DISEQC_ADDRESS_ANY_POLARISER = 0x20
+ * DISEQC_ADDRESS_LINEAR_POLARISER = 0x21
+ *
+ * DISEQC_ADDRESS_ANY_POSITIONER = 0x30
+ * DISEQC_ADDRESS_POLAR_AZIMUTH_POSITIONER = 0x31
+ * DISEQC_ADDRESS_ELEVATION_POSITIONER = 0x32
+ *
+ * DISEQC_ADDRESS_ANY_INSTALLER_AID = 0x40
+ * DISEQC_ADDRESS_SIGNAL_STRENGTH = 0x41
+ *
+ * DISEQC_ADDRESS_ANY_INTERFACE = 0x70
+ * DISEQC_ADDRESS_HEADEND_INTERFACE = 0x71
+ *
+ * DISEQC_ADDRESS_REALLOC_BASE = 0x60
+ * DISEQC_ADDRESS_OEM_BASE = 0xf0
+ */
+
+#ifndef DVBSEC_CFG_H
+#define DVBSEC_CFG_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <libdvbsec/dvbsec_api.h>
+
+/**
+ * Callback function used in dvbsec_cfg_load().
+ *
+ * @param arg Private information to caller.
+ * @param channel The current channel details.
+ * @return 0 to continue, 1 to stop loading.
+ */
+typedef int (*dvbsec_cfg_callback)(void *arg, struct dvbsec_config *sec);
+
+/**
+ * Load an SEC file.
+ *
+ * @param f File to load from.
+ * @param arg Value to pass to 'arg' in callback above.
+ * @param cb Callback function called for each sec loaded from the file.
+ * @return 0 on success, or nonzero error code on failure.
+ */
+extern int dvbsec_cfg_load(FILE *f, void *arg,
+ dvbsec_cfg_callback cb);
+
+/**
+ * Convenience function to parse an SEC config file. This will also consult the set
+ * of hardcoded defaults if no config file was supplied, or a match was not found in
+ * the config file.
+ *
+ * @param config_file Config filename to load, or NULL to just check defaults.
+ * @param sec_id ID of SEC configuration.
+ * @param sec Where to put the details if found.
+ * @return 0 on success, nonzero on error.
+ */
+extern int dvbsec_cfg_find(const char *config_file,
+ const char *sec_id,
+ struct dvbsec_config *sec);
+
+/**
+ * Save SEC format config file.
+ *
+ * @param f File to save to.
+ * @param secs Pointer to array of SECs to save.
+ * @param count Number of entries in the above array.
+ * @return 0 on success, or nonzero error code on failure.
+ */
+extern int dvbsec_cfg_save(FILE *f,
+ struct dvbsec_config *secs,
+ int count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/Makefile b/lib/libesg/Makefile
new file mode 100644
index 0000000..abb9d4f
--- /dev/null
+++ b/lib/libesg/Makefile
@@ -0,0 +1,27 @@
+# Makefile for linuxtv.org dvb-apps/lib/libesg
+
+includes = types.h
+
+objects = types.o
+
+lib_name = libesg
+
+CPPFLAGS += -I../../lib
+
+.PHONY: all
+
+all: library
+
+include bootstrap/Makefile
+include encapsulation/Makefile
+include representation/Makefile
+include transport/Makefile
+
+.PHONY: $(sub-install)
+
+install:: $(sub-install)
+
+$(sub-install):
+ $(MAKE) -C $@ install
+
+include ../../Make.rules
diff --git a/lib/libesg/TODO b/lib/libesg/TODO
new file mode 100644
index 0000000..952215a
--- /dev/null
+++ b/lib/libesg/TODO
@@ -0,0 +1,18 @@
+*** General
+- Add enums for constants
+
+*** EncodingVersion
+- GZIP : use zlib
+- BiM : ???
+
+*** BOOTSTRAP
+- ESGProviderDiscoveryDescriptor : XML parsing with libexpat ?
+
+*** TRANSPORT
+- Indexation
+
+*** ENCAPSULATION
+- Auxiliary Data
+
+*** REPRESENTATION
+- BiM Decoder Init
diff --git a/lib/libesg/bootstrap/Makefile b/lib/libesg/bootstrap/Makefile
new file mode 100644
index 0000000..16a2457
--- /dev/null
+++ b/lib/libesg/bootstrap/Makefile
@@ -0,0 +1,24 @@
+# Makefile for linuxtv.org dvb-apps/lib/libesg/bootstrap
+
+.PHONY: sub-error-bootstrap
+
+sub-error-bootstrap:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += bootstrap/access_descriptor.o \
+ bootstrap/provider_discovery_descriptor.o
+
+sub-install += bootstrap
+
+else
+
+includes = access_descriptor.h \
+ provider_discovery_descriptor.h
+
+include ../../../Make.rules
+
+lib_name = libesg/bootstrap
+
+endif
diff --git a/lib/libesg/bootstrap/access_descriptor.c b/lib/libesg/bootstrap/access_descriptor.c
new file mode 100644
index 0000000..e8f89a3
--- /dev/null
+++ b/lib/libesg/bootstrap/access_descriptor.c
@@ -0,0 +1,115 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/bootstrap/access_descriptor.h>
+
+struct esg_access_descriptor *esg_access_descriptor_decode(uint8_t *buffer, uint32_t size) {
+ uint32_t pos;
+ struct esg_access_descriptor *access_descriptor;
+ struct esg_entry *entry;
+ struct esg_entry *last_entry;
+ uint32_t entry_length;
+ uint16_t entry_index;
+ uint8_t ip_index;
+
+ if ((buffer == NULL) || (size <= 2)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ access_descriptor = (struct esg_access_descriptor *) malloc(sizeof(struct esg_access_descriptor));
+ memset(access_descriptor, 0, sizeof(struct esg_access_descriptor));
+ access_descriptor->entry_list = NULL;
+
+ access_descriptor->n_o_entries = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ last_entry = NULL;
+ for (entry_index = 0; entry_index < access_descriptor->n_o_entries; entry_index++) {
+ entry = (struct esg_entry *) malloc(sizeof(struct esg_entry));
+ memset(entry, 0, sizeof(struct esg_entry));
+ entry->_next = NULL;
+
+ if (last_entry == NULL) {
+ access_descriptor->entry_list = entry;
+ } else {
+ last_entry->_next = entry;
+ }
+ last_entry = entry;
+
+ entry->version = buffer[pos];
+ pos += 1;
+
+ pos += vluimsbf8(buffer + pos, size - pos, &entry_length);
+
+ if (size < pos + entry_length) {
+ esg_access_descriptor_free(access_descriptor);
+ return NULL;
+ }
+
+ entry->multiple_stream_transport = (buffer[pos] & 0x80) ? 1 : 0;
+ entry->ip_version_6 = (buffer[pos] & 0x40) ? 1 : 0;
+ pos += 1;
+
+ entry->provider_id = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ if (entry->ip_version_6) {
+ for (ip_index = 0; ip_index < 16; ip_index++) {
+ entry->source_ip.ipv6[ip_index] = buffer[pos+ip_index];
+ entry->destination_ip.ipv6[ip_index] = buffer[pos+16+ip_index];
+ }
+ pos += 32;
+ } else {
+ for (ip_index = 0; ip_index < 4; ip_index++) {
+ entry->source_ip.ipv4[ip_index] = buffer[pos+ip_index];
+ entry->destination_ip.ipv4[ip_index] = buffer[pos+4+ip_index];
+ }
+ pos += 8;
+ }
+ entry->port = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ entry->tsi = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+ }
+
+ return access_descriptor;
+}
+
+void esg_access_descriptor_free(struct esg_access_descriptor *access_descriptor) {
+ struct esg_entry *entry;
+ struct esg_entry *next_entry;
+
+ if (access_descriptor == NULL) {
+ return;
+ }
+
+ for(entry = access_descriptor->entry_list; entry; entry = next_entry) {
+ next_entry = entry->_next;
+ free(entry);
+ }
+
+ free(access_descriptor);
+}
diff --git a/lib/libesg/bootstrap/access_descriptor.h b/lib/libesg/bootstrap/access_descriptor.h
new file mode 100644
index 0000000..49aec46
--- /dev/null
+++ b/lib/libesg/bootstrap/access_descriptor.h
@@ -0,0 +1,86 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_BOOTSTRAP_ACCESS_DESCRIPTOR_H
+#define _ESG_BOOTSTRAP_ACCESS_DESCRIPTOR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libesg/types.h>
+
+/**
+ * esg_entry structure.
+ */
+struct esg_entry {
+ uint8_t version;
+ uint8_t multiple_stream_transport;
+ uint8_t ip_version_6;
+ uint16_t provider_id;
+ union esg_ip_address source_ip;
+ union esg_ip_address destination_ip;
+ uint16_t port;
+ uint16_t tsi;
+
+ struct esg_entry *_next;
+};
+
+/**
+ * esg_access_descriptor structure.
+ */
+struct esg_access_descriptor {
+ uint16_t n_o_entries;
+ struct esg_entry *entry_list;
+};
+
+/**
+ * Process an esg_access_descriptor.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_access_descriptor structure, or NULL on error.
+ */
+extern struct esg_access_descriptor *esg_access_descriptor_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_access_descriptor.
+ *
+ * @param esg Pointer to an esg_access_descriptor structure.
+ */
+extern void esg_access_descriptor_free(struct esg_access_descriptor *access_descriptor);
+
+/**
+ * Convenience iterator for esg_entry_list field of an esg_access_descriptor.
+ *
+ * @param access_descriptor The esg_access_descriptor pointer.
+ * @param entry Variable holding a pointer to the current esg_entry.
+ */
+#define esg_access_descriptor_entry_list_for_each(access_descriptor, entry) \
+ for ((entry) = (access_descriptor)->entry_list; \
+ (entry); \
+ (entry) = (entry)->_next)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/bootstrap/provider_discovery_descriptor.c b/lib/libesg/bootstrap/provider_discovery_descriptor.c
new file mode 100644
index 0000000..833a038
--- /dev/null
+++ b/lib/libesg/bootstrap/provider_discovery_descriptor.c
@@ -0,0 +1,50 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/bootstrap/provider_discovery_descriptor.h>
+
+struct esg_provider_discovery_descriptor *esg_esg_provider_discovery_descriptor_decode(uint8_t *buffer, uint32_t size) {
+ struct esg_provider_discovery_descriptor *provider;
+
+ provider = (struct esg_provider_discovery_descriptor *) malloc(sizeof(struct esg_provider_discovery_descriptor));
+ memset(provider, 0, sizeof(struct esg_provider_discovery_descriptor));
+
+ provider->xml = (uint8_t *) malloc(size);
+ memcpy(provider->xml, buffer, size);
+
+ provider->size = size;
+
+ return provider;
+}
+
+void esg_provider_discovery_descriptor_free(struct esg_provider_discovery_descriptor *provider) {
+ if (provider == NULL) {
+ return;
+ }
+
+ if (provider->xml) {
+ free(provider->xml);
+ }
+
+ free(provider);
+}
diff --git a/lib/libesg/bootstrap/provider_discovery_descriptor.h b/lib/libesg/bootstrap/provider_discovery_descriptor.h
new file mode 100644
index 0000000..36065ec
--- /dev/null
+++ b/lib/libesg/bootstrap/provider_discovery_descriptor.h
@@ -0,0 +1,59 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_BOOTSTRAP_PROVIDER_DISCOVERY_DESCRIPTOR_H
+#define _ESG_BOOTSTRAP_PROVIDER_DISCOVERY_DESCRIPTOR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_provider_discovery_descriptor structure.
+ */
+struct esg_provider_discovery_descriptor {
+ uint8_t *xml;
+ uint32_t size;
+};
+
+/**
+ * Process an esg_provider_discovery_descriptor.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_provider_discovery_descriptor structure, or NULL on error.
+ */
+extern struct esg_provider_discovery_descriptor *esg_esg_provider_discovery_descriptor_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_provider_discovery_descriptor.
+ *
+ * @param esg Pointer to an esg_provider_discovery_descriptor structure.
+ */
+extern void esg_provider_discovery_descriptor_free(struct esg_provider_discovery_descriptor *provider);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/encapsulation/Makefile b/lib/libesg/encapsulation/Makefile
new file mode 100644
index 0000000..2f222ed
--- /dev/null
+++ b/lib/libesg/encapsulation/Makefile
@@ -0,0 +1,28 @@
+# Makefile for linuxtv.org dvb-apps/lib/libesg/encapsulation
+
+.PHONY: sub-error-encapsulation
+
+sub-error-encapsulation:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += encapsulation/container.o \
+ encapsulation/fragment_management_information.o \
+ encapsulation/data_repository.o \
+ encapsulation/string_repository.o
+
+sub-install += encapsulation
+
+else
+
+includes = container.h \
+ fragment_management_information.h \
+ data_repository.h \
+ string_repository.h
+
+include ../../../Make.rules
+
+lib_name = libesg/encapsulation
+
+endif
diff --git a/lib/libesg/encapsulation/auxiliary_data.h b/lib/libesg/encapsulation/auxiliary_data.h
new file mode 100644
index 0000000..e05b241
--- /dev/null
+++ b/lib/libesg/encapsulation/auxiliary_data.h
@@ -0,0 +1,62 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_ENCAPSULATION_AUXILIARY_DATA_H
+#define _ESG_ENCAPSULATION_AUXILIARY_DATA_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_any_attribute structure.
+ */
+struct esg_any_attribute {
+ uint8_t version_id;
+ uint8_t *extension;
+
+ struct esg_any_attribure *_next;
+};
+
+/**
+ * esg_binary_header structure.
+ */
+struct esg_binary_header {
+ uint16_t encoding_metadatauri_mimetype;
+ struct esg_any_attribute *any_attribute_list;
+};
+
+/**
+ * esg_encapsulated_aux_data struct.
+ */
+struct esg_encapsulated_aux_data {
+ struct esg_binary_header *binary_header;
+ uint32_t aux_data_length;
+ uint8_t aux_data;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/encapsulation/container.c b/lib/libesg/encapsulation/container.c
new file mode 100644
index 0000000..15b17bf
--- /dev/null
+++ b/lib/libesg/encapsulation/container.c
@@ -0,0 +1,206 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/encapsulation/container.h>
+#include <libesg/encapsulation/fragment_management_information.h>
+#include <libesg/encapsulation/data_repository.h>
+#include <libesg/encapsulation/string_repository.h>
+#include <libesg/representation/init_message.h>
+#include <libesg/transport/session_partition_declaration.h>
+
+struct esg_container *esg_container_decode(uint8_t *buffer, uint32_t size) {
+ uint32_t pos;
+ struct esg_container *container;
+ struct esg_container_structure *structure;
+ struct esg_container_structure *last_structure;
+ uint8_t structure_index;
+
+ if ((buffer == NULL) || (size <= 1)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ container = (struct esg_container *) malloc(sizeof(struct esg_container));
+ memset(container, 0, sizeof(struct esg_container));
+
+ // Container header
+ container->header = (struct esg_container_header *) malloc(sizeof(struct esg_container_header));
+ memset(container->header, 0, sizeof(struct esg_container_header));
+
+ container->header->num_structures = buffer[pos];
+ pos += 1;
+
+ if (size < pos + (container->header->num_structures * 8)) {
+ esg_container_free(container);
+ return NULL;
+ }
+
+ last_structure = NULL;
+ for (structure_index = 0; structure_index < container->header->num_structures; structure_index++) {
+ structure = (struct esg_container_structure *) malloc(sizeof(struct esg_container_structure));
+ memset(structure, 0, sizeof(struct esg_container_structure));
+ structure->_next = NULL;
+
+ if (last_structure == NULL) {
+ container->header->structure_list = structure;
+ } else {
+ last_structure->_next = structure;
+ }
+ last_structure = structure;
+
+ structure->type = buffer[pos];
+ pos += 1;
+
+ structure->id = buffer[pos];
+ pos += 1;
+
+ structure->ptr = (buffer[pos] << 16) | (buffer[pos+1] << 8) | buffer[pos+2];
+ pos += 3;
+
+ structure->length = (buffer[pos] << 16) | (buffer[pos+1] << 8) | buffer[pos+2];
+ pos += 3;
+
+ if (size < (structure->ptr + structure->length)) {
+ esg_container_free(container);
+ return NULL;
+ }
+
+ // Decode structure
+ switch (structure->type) {
+ case 0x01: {
+ switch (structure->id) {
+ case 0x00: {
+ structure->data = (void *) esg_encapsulation_structure_decode(buffer + structure->ptr, structure->length);
+ break;
+ }
+ default: {
+ esg_container_free(container);
+ return NULL;
+ }
+ }
+ break;
+ }
+ case 0x02: {
+ switch (structure->id) {
+ case 0x00: {
+ structure->data = (void *) esg_string_repository_decode(buffer + structure->ptr, structure->length);
+ break;
+ }
+ default: {
+ esg_container_free(container);
+ return NULL;
+ }
+ }
+ break;
+ }
+ case 0x03: {
+ //TODO
+ break;
+ }
+ case 0x04: {
+ //TODO
+ break;
+ }
+ case 0x05: {
+ //TODO
+ break;
+ }
+ case 0xE0: {
+ switch (structure->id) {
+ case 0x00: {
+ structure->data = (void *) esg_data_repository_decode(buffer + structure->ptr, structure->length);
+ break;
+ }
+ default: {
+ esg_container_free(container);
+ return NULL;
+ }
+ }
+ break;
+ }
+ case 0xE1: {
+ switch (structure->id) {
+ case 0xFF: {
+ structure->data = (void *) esg_session_partition_declaration_decode(buffer + structure->ptr, structure->length);
+ break;
+ }
+ default: {
+ esg_container_free(container);
+ return NULL;
+ }
+ }
+ break;
+ }
+ case 0xE2: {
+ switch (structure->id) {
+ case 0x00: {
+ structure->data = (void *) esg_init_message_decode(buffer + structure->ptr, structure->length);
+ break;
+ }
+ default: {
+ esg_container_free(container);
+ return NULL;
+ }
+ }
+ break;
+ }
+ default: {
+ esg_container_free(container);
+ return NULL;
+ }
+ }
+ }
+
+ // Container structure body
+ container->structure_body_ptr = pos;
+ container->structure_body_length = size - pos;
+ container->structure_body = (uint8_t *) malloc(size - pos);
+ memcpy(container->structure_body, buffer + pos, size - pos);
+
+ return container;
+}
+
+void esg_container_free(struct esg_container *container) {
+ struct esg_container_structure *structure;
+ struct esg_container_structure *next_structure;
+
+ if (container == NULL) {
+ return;
+ }
+
+ if (container->header) {
+ for(structure = container->header->structure_list; structure; structure = next_structure) {
+ next_structure = structure->_next;
+ free(structure);
+ }
+
+ free(container->header);
+ }
+
+ if (container->structure_body) {
+ free(container->structure_body);
+ }
+
+ free(container);
+}
diff --git a/lib/libesg/encapsulation/container.h b/lib/libesg/encapsulation/container.h
new file mode 100644
index 0000000..dc54ef2
--- /dev/null
+++ b/lib/libesg/encapsulation/container.h
@@ -0,0 +1,94 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_ENCAPSULATION_CONTAINER_H
+#define _ESG_ENCAPSULATION_CONTAINER_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_container_structure structure.
+ */
+struct esg_container_structure {
+ uint8_t type;
+ uint8_t id;
+ uint32_t ptr;
+ uint32_t length;
+
+ void *data;
+
+ struct esg_container_structure *_next;
+};
+
+/**
+ * esg_container_header structure.
+ */
+struct esg_container_header {
+ uint8_t num_structures;
+ struct esg_container_structure *structure_list;
+};
+
+/**
+ * esg_container structure
+ */
+struct esg_container {
+ struct esg_container_header *header;
+ uint32_t structure_body_ptr;
+ uint32_t structure_body_length;
+ uint8_t *structure_body;
+};
+
+/**
+ * Process an esg_container.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_container structure, or NULL on error.
+ */
+extern struct esg_container *esg_container_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_container.
+ *
+ * @param container Pointer to an esg_container structure.
+ */
+extern void esg_container_free(struct esg_container *container);
+
+/**
+ * Convenience iterator for structure_list field of an esg_container_header.
+ *
+ * @param container The esg_container_header pointer.
+ * @param structure Variable holding a pointer to the current esg_container_structure.
+ */
+#define esg_container_header_structure_list_for_each(header, structure) \
+ for ((structure) = (header)->structure_list; \
+ (structure); \
+ (structure) = (structure)->_next)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/encapsulation/data_repository.c b/lib/libesg/encapsulation/data_repository.c
new file mode 100644
index 0000000..629e5ea
--- /dev/null
+++ b/lib/libesg/encapsulation/data_repository.c
@@ -0,0 +1,53 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/encapsulation/data_repository.h>
+
+struct esg_data_repository *esg_data_repository_decode(uint8_t *buffer, uint32_t size) {
+ struct esg_data_repository *data_repository;
+
+ if ((buffer == NULL) || (size <= 0)) {
+ return NULL;
+ }
+
+ data_repository = (struct esg_data_repository *) malloc(sizeof(struct esg_data_repository));
+ memset(data_repository, 0, sizeof(struct esg_data_repository));
+
+ data_repository->length = size;
+ data_repository->data = (uint8_t *) malloc(size);
+ memcpy(data_repository->data, buffer, size);
+
+ return data_repository;
+}
+
+void esg_data_repository_free(struct esg_data_repository *data_repository) {
+ if (data_repository == NULL) {
+ return;
+ }
+
+ if (data_repository->data) {
+ free(data_repository->data);
+ }
+
+ free(data_repository);
+}
diff --git a/lib/libesg/encapsulation/data_repository.h b/lib/libesg/encapsulation/data_repository.h
new file mode 100644
index 0000000..4c691cf
--- /dev/null
+++ b/lib/libesg/encapsulation/data_repository.h
@@ -0,0 +1,59 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_ENCAPSULATION_DATA_REPOSITORY_H
+#define _ESG_ENCAPSULATION_DATA_REPOSITORY_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_data_repository structure.
+ */
+struct esg_data_repository {
+ uint32_t length;
+ uint8_t *data;
+};
+
+/**
+ * Process an esg_data_repository.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_data_repository structure, or NULL on error.
+ */
+extern struct esg_data_repository *esg_data_repository_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_data_repository.
+ *
+ * @param data_repository Pointer to an esg_data_repository structure.
+ */
+extern void esg_data_repository_free(struct esg_data_repository *data_repository);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/encapsulation/fragment_management_information.c b/lib/libesg/encapsulation/fragment_management_information.c
new file mode 100644
index 0000000..b08265d
--- /dev/null
+++ b/lib/libesg/encapsulation/fragment_management_information.c
@@ -0,0 +1,118 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/encapsulation/fragment_management_information.h>
+
+struct esg_encapsulation_structure *esg_encapsulation_structure_decode(uint8_t *buffer, uint32_t size) {
+ uint32_t pos;
+ struct esg_encapsulation_structure *structure;
+ struct esg_encapsulation_entry *entry;
+ struct esg_encapsulation_entry *last_entry;
+
+ if ((buffer == NULL) || (size <= 2)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ structure = (struct esg_encapsulation_structure *) malloc(sizeof(struct esg_encapsulation_structure));
+ memset(structure, 0, sizeof(struct esg_encapsulation_structure));
+ structure->entry_list = NULL;
+
+ // Encapsulation header
+ structure->header = (struct esg_encapsulation_header *) malloc(sizeof(struct esg_encapsulation_header));
+ // buffer[pos] reserved
+ structure->header->fragment_reference_format = buffer[pos+1];
+ pos += 2;
+
+ // Encapsulation entry list
+ last_entry = NULL;
+ while (size > pos) {
+ entry = (struct esg_encapsulation_entry *) malloc(sizeof(struct esg_encapsulation_entry));
+ memset(entry, 0, sizeof(struct esg_encapsulation_entry));
+ entry->_next = NULL;
+
+ if (last_entry == NULL) {
+ structure->entry_list = entry;
+ } else {
+ last_entry->_next = entry;
+ }
+ last_entry = entry;
+
+ // Fragment reference
+ switch (structure->header->fragment_reference_format) {
+ case 0x21: {
+ entry->fragment_reference = (struct esg_fragment_reference *) malloc(sizeof(struct esg_fragment_reference));
+ memset(entry->fragment_reference, 0, sizeof(struct esg_fragment_reference));
+
+ entry->fragment_reference->fragment_type = buffer[pos];
+ pos += 1;
+
+ entry->fragment_reference->data_repository_offset = (buffer[pos] << 16) | (buffer[pos+1] << 8) | buffer[pos+2];
+ pos += 3;
+
+ break;
+ }
+ default: {
+ esg_encapsulation_structure_free(structure);
+ return NULL;
+ }
+ }
+
+ // Fragment version & id
+ entry->fragment_version = buffer[pos];
+ pos += 1;
+
+ entry->fragment_id = (buffer[pos] << 16) | (buffer[pos+1] << 8) | buffer[pos+2];
+ pos += 3;
+ }
+
+ return structure;
+}
+
+void esg_encapsulation_structure_free(struct esg_encapsulation_structure *structure) {
+ struct esg_encapsulation_entry *entry;
+ struct esg_encapsulation_entry *next_entry;
+
+ if (structure == NULL) {
+ return;
+ }
+
+ if (structure->header) {
+ free(structure->header);
+ }
+
+ if (structure->entry_list) {
+ for(entry = structure->entry_list; entry; entry = next_entry) {
+ next_entry = entry->_next;
+ if (entry->fragment_reference) {
+ free(entry->fragment_reference);
+ }
+ free(entry);
+ }
+
+ free(structure->entry_list);
+ }
+
+ free(structure);
+}
diff --git a/lib/libesg/encapsulation/fragment_management_information.h b/lib/libesg/encapsulation/fragment_management_information.h
new file mode 100644
index 0000000..04050b5
--- /dev/null
+++ b/lib/libesg/encapsulation/fragment_management_information.h
@@ -0,0 +1,96 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_ENCAPSULATION_FRAGMENT_MANAGEMENT_INFORMATION_H
+#define _ESG_ENCAPSULATION_FRAGMENT_MANAGEMENT_INFORMATION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_encapsulation_header structure.
+ */
+struct esg_encapsulation_header {
+ uint8_t fragment_reference_format;
+};
+
+/**
+ * esg_fragment_reference structure.
+ */
+struct esg_fragment_reference {
+ uint8_t fragment_type;
+ uint32_t data_repository_offset;
+};
+
+/**
+ * esg_encapsulation_entry structure.
+ */
+struct esg_encapsulation_entry {
+ struct esg_fragment_reference *fragment_reference;
+ uint8_t fragment_version;
+ uint32_t fragment_id;
+
+ struct esg_encapsulation_entry *_next;
+};
+
+/**
+ * esg_encapsulation_structure structure.
+ */
+struct esg_encapsulation_structure {
+ struct esg_encapsulation_header *header;
+ struct esg_encapsulation_entry *entry_list;
+};
+
+/**
+ * Process an esg_encapsulation_structure.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_encapsulation_structure structure, or NULL on error.
+ */
+extern struct esg_encapsulation_structure *esg_encapsulation_structure_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_encapsulation_structure.
+ *
+ * @param container Pointer to an esg_container structure.
+ */
+extern void esg_encapsulation_structure_free(struct esg_encapsulation_structure *structure);
+
+/**
+ * Convenience iterator for entry_list field of an esg_encapsulation_structure.
+ *
+ * @param structure The esg_encapsulation_structure pointer.
+ * @param entry Variable holding a pointer to the current esg_encapsulation_entry.
+ */
+#define esg_encapsulation_structure_entry_list_for_each(structure, entry) \
+ for ((entry) = (structure)->entry_list; \
+ (entry); \
+ (entry) = (entry)->_next)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/encapsulation/string_repository.c b/lib/libesg/encapsulation/string_repository.c
new file mode 100644
index 0000000..3b88742
--- /dev/null
+++ b/lib/libesg/encapsulation/string_repository.c
@@ -0,0 +1,54 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/encapsulation/string_repository.h>
+
+struct esg_string_repository *esg_string_repository_decode(uint8_t *buffer, uint32_t size) {
+ struct esg_string_repository *string_repository;
+
+ if ((buffer == NULL) || (size <= 1)) {
+ return NULL;
+ }
+
+ string_repository = (struct esg_string_repository *) malloc(sizeof(struct esg_string_repository));
+ memset(string_repository, 0, sizeof(struct esg_string_repository));
+
+ string_repository->encoding_type = buffer[0];
+ string_repository->length = size-1;
+ string_repository->data = (uint8_t *) malloc(size-1);
+ memcpy(string_repository->data, buffer+1, size-1);
+
+ return string_repository;
+}
+
+void esg_string_repository_free(struct esg_string_repository *string_repository) {
+ if (string_repository == NULL) {
+ return;
+ }
+
+ if (string_repository->data) {
+ free(string_repository->data);
+ }
+
+ free(string_repository);
+}
diff --git a/lib/libesg/encapsulation/string_repository.h b/lib/libesg/encapsulation/string_repository.h
new file mode 100644
index 0000000..0cf64c2
--- /dev/null
+++ b/lib/libesg/encapsulation/string_repository.h
@@ -0,0 +1,60 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_ENCAPSULATION_STRING_REPOSITORY_H
+#define _ESG_ENCAPSULATION_STRING_REPOSITORY_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_string_repository structure.
+ */
+struct esg_string_repository {
+ uint8_t encoding_type;
+ uint32_t length;
+ uint8_t *data;
+};
+
+/**
+ * Process an esg_string_repository.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_string_repository structure, or NULL on error.
+ */
+extern struct esg_string_repository *esg_string_repository_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_string_repository.
+ *
+ * @param data_repository Pointer to an esg_string_repository structure.
+ */
+extern void esg_string_repository_free(struct esg_string_repository *string_repository);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/representation/Makefile b/lib/libesg/representation/Makefile
new file mode 100644
index 0000000..059f8bd
--- /dev/null
+++ b/lib/libesg/representation/Makefile
@@ -0,0 +1,26 @@
+# Makefile for linuxtv.org dvb-apps/lib/libesg/representation
+
+.PHONY: sub-error-representation
+
+sub-error-representation:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += representation/encapsulated_textual_esg_xml_fragment.o \
+ representation/init_message.o \
+ representation/textual_decoder_init.o
+
+sub-install += representation
+
+else
+
+includes = encapsulated_textual_esg_xml_fragment.h \
+ init_message.h \
+ textual_decoder_init.h
+
+include ../../../Make.rules
+
+lib_name = libesg/representation
+
+endif
diff --git a/lib/libesg/representation/bim_decoder_init.h b/lib/libesg/representation/bim_decoder_init.h
new file mode 100644
index 0000000..4860da9
--- /dev/null
+++ b/lib/libesg/representation/bim_decoder_init.h
@@ -0,0 +1,40 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_REPRESENTATION_BIM_DECODER_INIT_H
+#define _ESG_REPRESENTATION_BIM_DECODER_INIT_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * esg_bim_decoder_init structure.
+ */
+struct esg_bim_decoder_init {
+// TODO
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/representation/encapsulated_bim_esg_xml_fragment.h b/lib/libesg/representation/encapsulated_bim_esg_xml_fragment.h
new file mode 100644
index 0000000..8ab39dd
--- /dev/null
+++ b/lib/libesg/representation/encapsulated_bim_esg_xml_fragment.h
@@ -0,0 +1,40 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_REPRESENTATION_ENCAPSULATED_BIM_ESG_XML_FRAGMENT_H
+#define _ESG_REPRESENTATION_ENCAPSULATED_BIM_ESG_XML_FRAGMENT_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * esg_encapsulated_bim_esg_xml_fragment structure.
+ */
+struct esg_encapsulated_bim_esg_xml_fragment {
+ //TODO
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/representation/encapsulated_textual_esg_xml_fragment.c b/lib/libesg/representation/encapsulated_textual_esg_xml_fragment.c
new file mode 100644
index 0000000..199c857
--- /dev/null
+++ b/lib/libesg/representation/encapsulated_textual_esg_xml_fragment.c
@@ -0,0 +1,70 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/types.h>
+#include <libesg/representation/encapsulated_textual_esg_xml_fragment.h>
+
+struct esg_encapsulated_textual_esg_xml_fragment *esg_encapsulated_textual_esg_xml_fragment_decode(uint8_t *buffer, uint32_t size) {
+ struct esg_encapsulated_textual_esg_xml_fragment *esg_xml_fragment;
+ uint32_t pos;
+ uint32_t length;
+ uint8_t offset_pos;
+
+ if ((buffer == NULL) || (size <= 0)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ esg_xml_fragment = (struct esg_encapsulated_textual_esg_xml_fragment *) malloc(sizeof(struct esg_encapsulated_textual_esg_xml_fragment));
+ memset(esg_xml_fragment, 0, sizeof(struct esg_encapsulated_textual_esg_xml_fragment));
+
+ offset_pos = vluimsbf8(buffer+pos+2, size-pos-2, &length);
+
+ if (size-pos-2 < offset_pos+length) {
+ esg_encapsulated_textual_esg_xml_fragment_free(esg_xml_fragment);
+ return NULL;
+ }
+
+ esg_xml_fragment->esg_xml_fragment_type = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2+offset_pos;
+
+ esg_xml_fragment->data_length = length;
+ esg_xml_fragment->data = (uint8_t *) malloc(length);
+ memcpy(esg_xml_fragment->data, buffer+pos, length);
+ pos += length;
+
+ return esg_xml_fragment;
+}
+
+void esg_encapsulated_textual_esg_xml_fragment_free(struct esg_encapsulated_textual_esg_xml_fragment *esg_xml_fragment) {
+ if (esg_xml_fragment == NULL) {
+ return;
+ }
+
+ if (esg_xml_fragment->data) {
+ free(esg_xml_fragment->data);
+ }
+
+ free(esg_xml_fragment);
+}
diff --git a/lib/libesg/representation/encapsulated_textual_esg_xml_fragment.h b/lib/libesg/representation/encapsulated_textual_esg_xml_fragment.h
new file mode 100644
index 0000000..ee8aba1
--- /dev/null
+++ b/lib/libesg/representation/encapsulated_textual_esg_xml_fragment.h
@@ -0,0 +1,60 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_REPRESENTATION_ENCAPSULATED_TEXTUAL_ESG_XML_FRAGMENT_H
+#define _ESG_REPRESENTATION_ENCAPSULATED_TEXTUAL_ESG_XML_FRAGMENT_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_encapsulated_textual_esg_xml_fragment structure.
+ */
+struct esg_encapsulated_textual_esg_xml_fragment {
+ uint16_t esg_xml_fragment_type;
+ uint32_t data_length;
+ uint8_t *data;
+};
+
+/**
+ * Process an esg_encapsulated_textual_esg_xml_fragment.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_encapsulated_textual_esg_xml_fragment structure, or NULL on error.
+ */
+extern struct esg_encapsulated_textual_esg_xml_fragment *esg_encapsulated_textual_esg_xml_fragment_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_encapsulated_textual_esg_xml_fragment.
+ *
+ * @param data_repository Pointer to an esg_encapsulated_textual_esg_xml_fragment structure.
+ */
+extern void esg_encapsulated_textual_esg_xml_fragment_free(struct esg_encapsulated_textual_esg_xml_fragment *esg_xml_fragment);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/representation/init_message.c b/lib/libesg/representation/init_message.c
new file mode 100644
index 0000000..0038607
--- /dev/null
+++ b/lib/libesg/representation/init_message.c
@@ -0,0 +1,112 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/representation/init_message.h>
+#include <libesg/representation/textual_decoder_init.h>
+#include <libesg/representation/bim_decoder_init.h>
+
+struct esg_init_message *esg_init_message_decode(uint8_t *buffer, uint32_t size) {
+ uint32_t pos;
+ struct esg_init_message *init_message;
+
+ if ((buffer == NULL) || (size <= 3)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ init_message = (struct esg_init_message *) malloc(sizeof(struct esg_init_message));
+ memset(init_message, 0, sizeof(struct esg_init_message));
+
+ init_message->encoding_version = buffer[pos];
+ pos += 1;
+
+ init_message->indexing_flag = (buffer[pos] & 0x80) >> 7;
+ pos += 1;
+
+ init_message->decoder_init_ptr = buffer[pos];
+ pos += 1;
+
+ if (init_message->indexing_flag) {
+ init_message->indexing_version = buffer[pos];
+ pos += 1;
+ }
+
+ switch (init_message->encoding_version) {
+ case 0xF1: {
+ struct esg_bim_encoding_parameters *encoding_parameters = (struct esg_bim_encoding_parameters *) malloc(sizeof(struct esg_bim_encoding_parameters));
+ memset(encoding_parameters, 0, sizeof(struct esg_bim_encoding_parameters));
+ init_message->encoding_parameters = (void *) encoding_parameters;
+
+ encoding_parameters->buffer_size_flag = (buffer[pos] & 0x80) >> 7;
+ encoding_parameters->position_code_flag = (buffer[pos] & 0x40) >> 6;
+ pos += 1;
+
+ encoding_parameters->character_encoding = buffer[pos];
+ pos += 1;
+
+ if (encoding_parameters->buffer_size_flag) {
+ encoding_parameters->buffer_size = (buffer[pos] << 16) | (buffer[pos+1] << 8) | buffer[pos+2];
+ pos += 3;
+ }
+
+// TODO
+// init_message->decoder_init = (void *) esg_bim_decoder_init_decode(buffer + init_message->decoder_init_ptr, size - init_message->decoder_init_ptr);
+ break;
+ }
+ case 0xF2:
+ case 0xF3: {
+ struct esg_textual_encoding_parameters *encoding_parameters = (struct esg_textual_encoding_parameters *) malloc(sizeof(struct esg_textual_encoding_parameters));
+ memset(encoding_parameters, 0, sizeof(struct esg_textual_encoding_parameters));
+ init_message->encoding_parameters = (void *) encoding_parameters;
+
+ encoding_parameters->character_encoding = buffer[pos];
+ pos += 1;
+
+ init_message->decoder_init = (void *) esg_textual_decoder_init_decode(buffer + init_message->decoder_init_ptr, size - init_message->decoder_init_ptr);
+ break;
+ }
+ default: {
+ esg_init_message_free(init_message);
+ return NULL;
+ }
+ }
+
+ return init_message;
+}
+
+void esg_init_message_free(struct esg_init_message *init_message) {
+ if (init_message == NULL) {
+ return;
+ }
+
+ if (init_message->encoding_parameters) {
+ free(init_message->encoding_parameters);
+ }
+
+ if (init_message->decoder_init) {
+ free(init_message->decoder_init);
+ }
+
+ free(init_message);
+}
diff --git a/lib/libesg/representation/init_message.h b/lib/libesg/representation/init_message.h
new file mode 100644
index 0000000..a525495
--- /dev/null
+++ b/lib/libesg/representation/init_message.h
@@ -0,0 +1,80 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_REPRESENTATION_INIT_MESSAGE_H
+#define _ESG_REPRESENTATION_INIT_MESSAGE_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_textual_encoding_parameters structure.
+ */
+struct esg_textual_encoding_parameters {
+ uint8_t character_encoding;
+};
+
+/**
+ * esg_bim_encoding_parameters structure.
+ */
+struct esg_bim_encoding_parameters {
+ uint8_t buffer_size_flag;
+ uint8_t position_code_flag;
+ uint8_t character_encoding;
+ uint32_t buffer_size; // if buffer_size_flag
+};
+
+/**
+ * esg_init_message structure.
+ */
+struct esg_init_message {
+ uint8_t encoding_version;
+ uint8_t indexing_flag;
+ uint8_t decoder_init_ptr;
+ uint8_t indexing_version; // if indexing_flag
+ void *encoding_parameters;
+ void *decoder_init;
+};
+
+/**
+ * Process an esg_init_message.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_string_repository structure, or NULL on error.
+ */
+extern struct esg_init_message *esg_init_message_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_init_message.
+ *
+ * @param init_message Pointer to an esg_init_message structure.
+ */
+extern void esg_init_message_free(struct esg_init_message *init_message);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/representation/textual_decoder_init.c b/lib/libesg/representation/textual_decoder_init.c
new file mode 100644
index 0000000..c797d0e
--- /dev/null
+++ b/lib/libesg/representation/textual_decoder_init.c
@@ -0,0 +1,128 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/types.h>
+#include <libesg/representation/textual_decoder_init.h>
+
+struct esg_textual_decoder_init *esg_textual_decoder_init_decode(uint8_t *buffer, uint32_t size) {
+ uint32_t pos;
+ struct esg_textual_decoder_init *decoder_init;
+ struct esg_namespace_prefix *namespace_prefix;
+ struct esg_namespace_prefix *last_namespace_prefix;
+ struct esg_xml_fragment_type *xml_fragment_type;
+ struct esg_xml_fragment_type *last_xml_fragment_type;
+ uint32_t decoder_init_length;
+ uint8_t num_index;
+
+ if ((buffer == NULL) || (size <= 1)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ decoder_init = (struct esg_textual_decoder_init *) malloc(sizeof(struct esg_textual_decoder_init));
+ memset(decoder_init, 0, sizeof(struct esg_textual_decoder_init));
+ decoder_init->namespace_prefix_list = NULL;
+ decoder_init->xml_fragment_type_list = NULL;
+
+ decoder_init->version = buffer[pos];
+ pos += 1;
+
+ pos += vluimsbf8(buffer+pos, size-pos, &decoder_init_length);
+
+ if (size < pos + decoder_init_length) {
+ esg_textual_decoder_init_free(decoder_init);
+ return NULL;
+ }
+
+ decoder_init->num_namespace_prefixes = buffer[pos];
+ pos += 1;
+
+ last_namespace_prefix = NULL;
+ for (num_index = 0; num_index < decoder_init->num_namespace_prefixes; num_index++) {
+ namespace_prefix = (struct esg_namespace_prefix *) malloc(sizeof(struct esg_namespace_prefix));
+ memset(namespace_prefix, 0, sizeof(struct esg_namespace_prefix));
+ namespace_prefix->_next = NULL;
+
+ if (last_namespace_prefix == NULL) {
+ decoder_init->namespace_prefix_list = namespace_prefix;
+ } else {
+ last_namespace_prefix->_next = namespace_prefix;
+ }
+ last_namespace_prefix = namespace_prefix;
+
+ namespace_prefix->prefix_string_ptr = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ namespace_prefix->namespace_uri_ptr = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+ }
+
+ decoder_init->num_fragment_types = buffer[pos];
+ pos += 1;
+
+ last_xml_fragment_type = NULL;
+ for (num_index = 0; num_index < decoder_init->num_fragment_types; num_index++) {
+ xml_fragment_type = (struct esg_xml_fragment_type *) malloc(sizeof(struct esg_xml_fragment_type));
+ memset(xml_fragment_type, 0, sizeof(struct esg_xml_fragment_type));
+ xml_fragment_type->_next = NULL;
+
+ if (last_xml_fragment_type == NULL) {
+ decoder_init->xml_fragment_type_list = xml_fragment_type;
+ } else {
+ last_xml_fragment_type->_next = xml_fragment_type;
+ }
+ last_xml_fragment_type = xml_fragment_type;
+
+ xml_fragment_type->xpath_ptr = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ xml_fragment_type->xml_fragment_type = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+ }
+
+ return decoder_init;
+}
+
+void esg_textual_decoder_init_free(struct esg_textual_decoder_init *decoder_init) {
+ struct esg_namespace_prefix *namespace_prefix;
+ struct esg_namespace_prefix *next_namespace_prefix;
+ struct esg_xml_fragment_type *xml_fragment_type;
+ struct esg_xml_fragment_type *next_xml_fragment_type;
+
+ if (decoder_init == NULL) {
+ return;
+ }
+
+ for(namespace_prefix = decoder_init->namespace_prefix_list; namespace_prefix; namespace_prefix = next_namespace_prefix) {
+ next_namespace_prefix = namespace_prefix->_next;
+ free(namespace_prefix);
+ }
+
+ for(xml_fragment_type = decoder_init->xml_fragment_type_list; xml_fragment_type; xml_fragment_type = next_xml_fragment_type) {
+ next_xml_fragment_type = xml_fragment_type->_next;
+ free(xml_fragment_type);
+ }
+
+ free(decoder_init);
+}
diff --git a/lib/libesg/representation/textual_decoder_init.h b/lib/libesg/representation/textual_decoder_init.h
new file mode 100644
index 0000000..c1352cc
--- /dev/null
+++ b/lib/libesg/representation/textual_decoder_init.h
@@ -0,0 +1,104 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_REPRESENTATION_TEXTUAL_DECODER_INIT_H
+#define _ESG_REPRESENTATION_TEXTUAL_DECODER_INIT_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_namespace_prefix structure.
+ */
+struct esg_namespace_prefix {
+ uint16_t prefix_string_ptr;
+ uint16_t namespace_uri_ptr;
+
+ struct esg_namespace_prefix *_next;
+};
+
+/**
+ * esg_fragment_type structure.
+ */
+struct esg_xml_fragment_type {
+ uint16_t xpath_ptr;
+ uint16_t xml_fragment_type;
+
+ struct esg_xml_fragment_type *_next;
+};
+
+/**
+ * esg_textual_decoder_init structure.
+ */
+struct esg_textual_decoder_init {
+ uint8_t version;
+ uint8_t num_namespace_prefixes;
+ struct esg_namespace_prefix *namespace_prefix_list;
+ uint8_t num_fragment_types;
+ struct esg_xml_fragment_type *xml_fragment_type_list;
+};
+
+/**
+ * Process an esg_textual_decoder_init.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_textual_decoder_init structure, or NULL on error.
+ */
+extern struct esg_textual_decoder_init *esg_textual_decoder_init_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_textual_decoder_init.
+ *
+ * @param decoder_init Pointer to an esg_textual_decoder_init structure.
+ */
+extern void esg_textual_decoder_init_free(struct esg_textual_decoder_init *decoder_init);
+
+/**
+ * Convenience iterator for namespace_prefix_list field of an esg_textual_decoder_init.
+ *
+ * @param decoder_init The esg_textual_decoder_init pointer.
+ * @param namespace_prefix Variable holding a pointer to the current esg_namespace_prefix.
+ */
+#define esg_textual_decoder_namespace_prefix_list_for_each(decoder_init, namespace_prefix) \
+ for ((namespace_prefix) = (decoder_init)->namespace_prefix_list; \
+ (namespace_prefix); \
+ (namespace_prefix) = (namespace_prefix)->_next)
+
+/**
+ * Convenience iterator for xml_fragment_type_list field of an esg_textual_decoder_init.
+ *
+ * @param decoder_init The esg_textual_decoder_init pointer.
+ * @param xml_fragment_type Variable holding a pointer to the current esg_xml_fragment_type.
+ */
+#define esg_textual_decoder_xml_fragment_type_list_for_each(decoder_init, xml_fragment_type) \
+ for ((xml_fragment_type) = (decoder_init)->xml_fragment_type_list; \
+ (xml_fragment_type); \
+ (xml_fragment_type) = (xml_fragment_type)->_next)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/transport/Makefile b/lib/libesg/transport/Makefile
new file mode 100644
index 0000000..7900770
--- /dev/null
+++ b/lib/libesg/transport/Makefile
@@ -0,0 +1,22 @@
+# Makefile for linuxtv.org dvb-apps/lib/libesg/transport
+
+.PHONY: sub-error-transport
+
+sub-error-transport:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += transport/session_partition_declaration.o
+
+sub-install += transport
+
+else
+
+includes = session_partition_declaration.h
+
+include ../../../Make.rules
+
+lib_name = libesg/transport
+
+endif
diff --git a/lib/libesg/transport/session_partition_declaration.c b/lib/libesg/transport/session_partition_declaration.c
new file mode 100644
index 0000000..d590bd3
--- /dev/null
+++ b/lib/libesg/transport/session_partition_declaration.c
@@ -0,0 +1,253 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libesg/transport/session_partition_declaration.h>
+
+struct esg_session_partition_declaration *esg_session_partition_declaration_decode(uint8_t *buffer, uint32_t size) {
+ uint32_t pos;
+ struct esg_session_partition_declaration *partition;
+ struct esg_session_field *field;
+ struct esg_session_field *last_field;
+ uint8_t field_index;
+ struct esg_session_ip_stream *ip_stream;
+ struct esg_session_ip_stream *last_ip_stream;
+ uint8_t ip_stream_index;
+ uint8_t ip_index;
+ struct esg_session_ip_stream_field *ip_stream_field;
+ struct esg_session_ip_stream_field *last_ip_stream_field;
+ uint8_t *field_buffer;
+ uint32_t field_length;
+ union esg_session_ip_stream_field_value *field_value;
+
+ if ((buffer == NULL) || (size <= 2)) {
+ return NULL;
+ }
+
+ pos = 0;
+
+ partition = (struct esg_session_partition_declaration *) malloc(sizeof(struct esg_session_partition_declaration));
+ memset(partition, 0, sizeof(struct esg_session_partition_declaration));
+ partition->field_list = NULL;
+ partition->ip_stream_list = NULL;
+
+ partition->num_fields = buffer[pos];
+ pos += 1;
+
+ partition->overlapping = (buffer[pos] & 0x80) ? 1 : 0;
+ pos += 1;
+
+ if (size < (pos + 5*(partition->num_fields))) {
+ esg_session_partition_declaration_free(partition);
+ return NULL;
+ }
+
+ last_field = NULL;
+ for (field_index = 0; field_index < partition->num_fields; field_index++) {
+ field = (struct esg_session_field *) malloc(sizeof(struct esg_session_field));
+ memset(field, 0, sizeof(struct esg_session_field));
+ field->_next = NULL;
+
+ if (last_field == NULL) {
+ partition->field_list = field;
+ } else {
+ last_field->_next = field;
+ }
+ last_field = field;
+
+ field->identifier = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ field->encoding = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ field->length = buffer[pos];
+ pos += 1;
+ }
+
+ partition->n_o_ip_streams = buffer[pos];
+ pos += 1;
+
+ partition->ip_version_6 = (buffer[pos] & 0x80) ? 1 : 0;
+ pos += 1;
+
+ last_ip_stream = NULL;
+ for (ip_stream_index = 0; ip_stream_index < partition->n_o_ip_streams; ip_stream_index++) {
+ ip_stream = (struct esg_session_ip_stream *) malloc(sizeof(struct esg_session_ip_stream));
+ memset(ip_stream, 0, sizeof(struct esg_session_ip_stream));
+ ip_stream->_next = NULL;
+
+ if (last_ip_stream == NULL) {
+ partition->ip_stream_list = ip_stream;
+ } else {
+ last_ip_stream->_next = ip_stream;
+ }
+ last_ip_stream = ip_stream;
+
+ ip_stream->id = buffer[pos];
+ pos += 1;
+
+ if (partition->ip_version_6) {
+ for (ip_index = 0; ip_index < 16; ip_index++) {
+ ip_stream->source_ip.ipv6[ip_index] = buffer[pos+ip_index];
+ ip_stream->destination_ip.ipv6[ip_index] = buffer[pos+16+ip_index];
+ }
+ pos += 32;
+ } else {
+ for (ip_index = 0; ip_index < 4; ip_index++) {
+ ip_stream->source_ip.ipv4[ip_index] = buffer[pos+ip_index];
+ ip_stream->destination_ip.ipv4[ip_index] = buffer[pos+4+ip_index];
+ }
+ pos += 8;
+ }
+ ip_stream->port = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ ip_stream->session_id = (buffer[pos] << 8) | buffer[pos+1];
+ pos += 2;
+
+ last_ip_stream_field = NULL;
+ esg_session_partition_declaration_field_list_for_each(partition, field) {
+ ip_stream_field = (struct esg_session_ip_stream_field *) malloc(sizeof(struct esg_session_ip_stream_field));
+ memset(ip_stream_field, 0, sizeof(struct esg_session_ip_stream_field));
+ ip_stream_field->_next = NULL;
+ ip_stream_field->start_field_value = NULL;
+ ip_stream_field->end_field_value = NULL;
+
+ if (last_ip_stream_field == NULL) {
+ ip_stream->field_list = ip_stream_field;
+ } else {
+ last_ip_stream_field->_next = ip_stream_field;
+ }
+ last_ip_stream_field = ip_stream_field;
+
+ field_length = field->length;
+ if (field->length != 0) {
+ field_length = field->length;
+ } else {
+ pos += vluimsbf8(buffer + pos, size - pos, &field_length);
+ }
+
+ switch (field->encoding) {
+ case 0x0000: {
+ if (partition->overlapping == 1) {
+ field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
+ memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
+ ip_stream_field->start_field_value = field_value;
+
+ field_buffer = (uint8_t *) malloc(field_length);
+ memset(field_buffer, 0, field_length);
+ memcpy(field_buffer, buffer + pos, field_length);
+
+ ip_stream_field->start_field_value->string = field_buffer;
+ pos += field_length;
+ }
+ field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
+ memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
+ ip_stream_field->end_field_value = field_value;
+
+ field_buffer = (uint8_t *) malloc(field_length);
+ memset(field_buffer, 0, field_length);
+ memcpy(field_buffer, buffer + pos, field_length);
+
+ ip_stream_field->end_field_value->string = field_buffer;
+ pos += field_length;
+
+ break;
+ }
+ case 0x0101: {
+ if (partition->overlapping == 1) {
+ field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
+ memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
+ ip_stream_field->start_field_value = field_value;
+
+ ip_stream_field->start_field_value->unsigned_short = (buffer[pos] << 8) | buffer[pos+1];
+ pos += field_length;
+ }
+ field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
+ memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
+ ip_stream_field->end_field_value = field_value;
+
+ ip_stream_field->end_field_value->unsigned_short = (buffer[pos] << 8) | buffer[pos+1];
+ pos += field_length;
+
+ break;
+ }
+ default: {
+ esg_session_partition_declaration_free(partition);
+ return NULL;
+ }
+ }
+ }
+ }
+
+ return partition;
+}
+
+void esg_session_partition_declaration_free(struct esg_session_partition_declaration *partition) {
+ struct esg_session_field *field;
+ struct esg_session_field *next_field;
+ struct esg_session_ip_stream *ip_stream;
+ struct esg_session_ip_stream *next_ip_stream;
+ struct esg_session_ip_stream_field *ip_stream_field;
+ struct esg_session_ip_stream_field *next_ip_stream_field;
+
+ if (partition == NULL) {
+ return;
+ }
+
+ for(ip_stream = partition->ip_stream_list; ip_stream; ip_stream = next_ip_stream) {
+ next_ip_stream = ip_stream->_next;
+
+ field = partition->field_list;
+ for(ip_stream_field = next_ip_stream->field_list; ip_stream_field; ip_stream_field = next_ip_stream_field) {
+ next_ip_stream_field = ip_stream_field->_next;
+
+ switch (field->encoding) {
+ case 0x0000: {
+ if (ip_stream_field->start_field_value != NULL) {
+ free(ip_stream_field->start_field_value->string);
+ }
+ free(ip_stream_field->end_field_value->string);
+ break;
+ }
+ case 0x0101: {
+ // Nothing to free
+ break;
+ }
+ }
+
+ free(ip_stream_field);
+
+ field = field->_next;
+ }
+
+ free(ip_stream);
+ }
+
+ for(field = partition->field_list; field; field = next_field) {
+ next_field = field->_next;
+ free(field);
+ }
+
+ free(partition);
+}
diff --git a/lib/libesg/transport/session_partition_declaration.h b/lib/libesg/transport/session_partition_declaration.h
new file mode 100644
index 0000000..8f2fa1a
--- /dev/null
+++ b/lib/libesg/transport/session_partition_declaration.h
@@ -0,0 +1,139 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_TRANSPORT_SESSION_PARTITION_DECLARATION_H
+#define _ESG_TRANSPORT_SESSION_PARTITION_DECLARATION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libesg/types.h>
+
+/**
+ * esg_session_field structure.
+ */
+struct esg_session_field {
+ uint16_t identifier;
+ uint16_t encoding;
+ uint8_t length;
+
+ struct esg_session_field *_next;
+};
+
+/**
+ * esg_session_ip_stream_field_value union.
+ */
+union esg_session_ip_stream_field_value {
+ uint8_t *string;
+ uint16_t unsigned_short;
+};
+
+/**
+ * esg_session_ip_stream_field structure.
+ */
+struct esg_session_ip_stream_field {
+ union esg_session_ip_stream_field_value *start_field_value;
+ union esg_session_ip_stream_field_value *end_field_value;
+
+ struct esg_session_ip_stream_field *_next;
+};
+
+/**
+ * esg_session_ip_stream structure.
+ */
+struct esg_session_ip_stream {
+ uint8_t id;
+ union esg_ip_address source_ip;
+ union esg_ip_address destination_ip;
+ uint16_t port;
+ uint16_t session_id;
+ struct esg_session_ip_stream_field *field_list;
+
+ struct esg_session_ip_stream *_next;
+};
+
+/**
+ * esg_session_partition_declaration structure.
+ */
+struct esg_session_partition_declaration {
+ uint8_t num_fields;
+ uint8_t overlapping;
+ struct esg_session_field *field_list;
+ uint8_t n_o_ip_streams;
+ uint8_t ip_version_6;
+ struct esg_session_ip_stream *ip_stream_list;
+};
+
+/**
+ * Process an esg_session_partition_declaration.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @return Pointer to an esg_session_partition_declaration structure, or NULL on error.
+ */
+extern struct esg_session_partition_declaration *esg_session_partition_declaration_decode(uint8_t *buffer, uint32_t size);
+
+/**
+ * Free an esg_session_partition_declaration.
+ *
+ * @param esg Pointer to an esg_session_partition_declaration structure.
+ */
+extern void esg_session_partition_declaration_free(struct esg_session_partition_declaration *partition);
+
+/**
+ * Convenience iterator for field_list field of an esg_session_partition_declaration.
+ *
+ * @param partition The esg_session_partition_declaration pointer.
+ * @param field Variable holding a pointer to the current esg_session_field.
+ */
+#define esg_session_partition_declaration_field_list_for_each(partition, field) \
+ for ((field) = (partition)->field_list; \
+ (field); \
+ (field) = (field)->_next)
+
+/**
+ * Convenience iterator for ip_stream_list field of an esg_session_partition_declaration.
+ *
+ * @param partition The esg_session_partition_declaration pointer.
+ * @param ip_stream Variable holding a pointer to the current esg_session_ip_stream.
+ */
+#define esg_session_partition_declaration_ip_stream_list_for_each(partition, ip_stream) \
+ for ((ip_stream) = (partition)->ip_stream_list; \
+ (ip_stream); \
+ (ip_stream) = (ip_stream)->_next)
+
+/**
+ * Convenience iterator for field_list field of an esg_session_ip_stream.
+ *
+ * @param ip_stream The esg_session_ip_stream pointer.
+ * @param field Variable holding a pointer to the current esg_session_ip_stream.
+ */
+#define esg_session_ip_stream_field_list_for_each(ip_stream, field) \
+ for ((field) = (ip_stream)->field_list; \
+ (field); \
+ (field) = (field)->_next)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/types.c b/lib/libesg/types.c
new file mode 100644
index 0000000..51f1cbd
--- /dev/null
+++ b/lib/libesg/types.c
@@ -0,0 +1,37 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libesg/types.h>
+
+uint8_t vluimsbf8(uint8_t *buffer, uint32_t size, uint32_t *length) {
+ uint8_t offset = 0;
+ *length = 0;
+
+ do {
+ if (size < offset) {
+ offset = 0;
+ *length = 0;
+ break;
+ }
+ *length = (*length << 7) + (buffer[offset] & 0x7F);
+ } while (buffer[offset++] & 0x80);
+
+ return offset;
+}
diff --git a/lib/libesg/types.h b/lib/libesg/types.h
new file mode 100644
index 0000000..b6725af
--- /dev/null
+++ b/lib/libesg/types.h
@@ -0,0 +1,53 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _ESG_TYPES_H
+#define _ESG_TYPES_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/**
+ * esg_ip_address
+ */
+union esg_ip_address {
+ uint8_t ipv4[4];
+ uint8_t ipv6[16];
+};
+
+/**
+ * Process a vluimsbf8 length.
+ *
+ * @param buffer Binary buffer to decode.
+ * @param size Binary buffer size.
+ * @param length Read length value
+ * @return vluimsbf8 size
+ */
+extern uint8_t vluimsbf8(uint8_t *buffer, uint32_t size, uint32_t *length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libesg/xml/provider_discovery_descriptor.xsd b/lib/libesg/xml/provider_discovery_descriptor.xsd
new file mode 100644
index 0000000..5956343
--- /dev/null
+++ b/lib/libesg/xml/provider_discovery_descriptor.xsd
@@ -0,0 +1,22 @@
+<schema targetNamespace="urn:dvb:ipdc:esgbs:2005" xmlns:bs="urn:dvb:ipdc:esgbs:2005"
+ xmlns:mpeg7="urn:mpeg:mpeg7:schema:2001" xmlns="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+ <import namespace="urn:mpeg:mpeg7:schema:2001" />
+ <complexType name="ESGProviderType">
+ <sequence>
+ <element name="ProviderURI" type="anyURI"/>
+ <element name="ProviderName" type="mpeg7:TextualType"/>
+ <element name="ProviderLogo" type="mpeg7:TitleMediaType" minOccurs="0"/>
+ <element name="ProviderID" type="positiveInteger"/>
+ <element name="ProviderInformationURL" type="anyURI" minOccurs="0"/>
+ <element name="PrivateAuxiliaryData" type="anyType" minOccurs="0"/>
+ </sequence>
+ </complexType>
+ <element name="ESGProviderDiscovery">
+ <complexType>
+ <sequence>
+ <element name="ServiceProvider" type="bs:ESGProviderType" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+ </element>
+</schema>
diff --git a/lib/libucsi/Makefile b/lib/libucsi/Makefile
new file mode 100644
index 0000000..19ab268
--- /dev/null
+++ b/lib/libucsi/Makefile
@@ -0,0 +1,34 @@
+# Makefile for linuxtv.org dvb-apps/lib/libucsi
+
+includes = crc32.h \
+ descriptor.h \
+ endianops.h \
+ section.h \
+ section_buf.h \
+ transport_packet.h \
+ types.h
+
+objects = crc32.o \
+ section_buf.o \
+ transport_packet.o
+
+lib_name = libucsi
+
+CPPFLAGS += -I../../lib
+
+.PHONY: all
+
+all: library
+
+include atsc/Makefile
+include dvb/Makefile
+include mpeg/Makefile
+
+.PHONY: $(sub-install)
+
+install:: $(sub-install)
+
+$(sub-install):
+ $(MAKE) -C $@ install
+
+include ../../Make.rules
diff --git a/lib/libucsi/atsc/Makefile b/lib/libucsi/atsc/Makefile
new file mode 100644
index 0000000..c3d8e6b
--- /dev/null
+++ b/lib/libucsi/atsc/Makefile
@@ -0,0 +1,55 @@
+# Makefile for linuxtv.org dvb-apps/lib/libucsi/atsc
+
+.PHONY: sub-error-atsc
+
+sub-error-atsc:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += atsc/atsc_text.o \
+ atsc/cvct_section.o \
+ atsc/dccsct_section.o \
+ atsc/dcct_section.o \
+ atsc/eit_section.o \
+ atsc/ett_section.o \
+ atsc/mgt_section.o \
+ atsc/rrt_section.o \
+ atsc/stt_section.o \
+ atsc/tvct_section.o \
+ atsc/types.o
+
+sub-install += atsc
+
+else
+
+includes = ac3_descriptor.h \
+ caption_service_descriptor.h \
+ component_name_descriptor.h \
+ content_advisory_descriptor.h \
+ cvct_section.h \
+ dcc_arriving_request_descriptor.h \
+ dcc_departing_request_descriptor.h \
+ dccsct_section.h \
+ dcct_section.h \
+ descriptor.h \
+ eit_section.h \
+ ett_section.h \
+ extended_channel_name_descriptor.h \
+ genre_descriptor.h \
+ mgt_section.h \
+ rc_descriptor.h \
+ rrt_section.h \
+ section.h \
+ service_location_descriptor.h \
+ stt_section.h \
+ stuffing_descriptor.h \
+ time_shifted_service_descriptor.h \
+ tvct_section.h \
+ types.h
+
+include ../../../Make.rules
+
+lib_name = libucsi/atsc
+
+endif
diff --git a/lib/libucsi/atsc/ac3_descriptor.h b/lib/libucsi/atsc/ac3_descriptor.h
new file mode 100644
index 0000000..489695b
--- /dev/null
+++ b/lib/libucsi/atsc/ac3_descriptor.h
@@ -0,0 +1,112 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_atsc@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_AC3_DESCRIPTOR
+#define _UCSI_ATSC_AC3_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+enum atsc_ac3_channels {
+ ATSC_AC3_CHANNELS_1_PLUS_1 = 0x0,
+ ATSC_AC3_CHANNELS_1_0 = 0x1,
+ ATSC_AC3_CHANNELS_2_0 = 0x2,
+ ATSC_AC3_CHANNELS_3_0 = 0x3,
+ ATSC_AC3_CHANNELS_2_1 = 0x4,
+ ATSC_AC3_CHANNELS_3_1 = 0x5,
+ ATSC_AC3_CHANNELS_2_2 = 0x6,
+ ATSC_AC3_CHANNELS_3_2 = 0x7,
+ ATSC_AC3_CHANNELS_1 = 0x8,
+ ATSC_AC3_CHANNELS_LTEQ_2 = 0x9,
+ ATSC_AC3_CHANNELS_LTEQ_3 = 0xa,
+ ATSC_AC3_CHANNELS_LTEQ_4 = 0xb,
+ ATSC_AC3_CHANNELS_LTEQ_5 = 0xc,
+ ATSC_AC3_CHANNELS_LTEQ_6 = 0xd,
+};
+
+/**
+ * atsc_ac3_descriptor structure.
+ */
+struct atsc_ac3_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t sample_rate_code : 3; ,
+ uint8_t bsid : 5; );
+ EBIT2(uint8_t bit_rate_code : 6; ,
+ uint8_t surround_mode : 2; );
+ EBIT3(uint8_t bsmod : 3; ,
+ uint8_t num_channels : 4; ,
+ uint8_t full_svc : 1; );
+ /* uint8_t additional_info[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_ac3_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return atsc_ac3_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_ac3_descriptor*
+ atsc_ac3_descriptor_codec(struct descriptor* d)
+{
+ int pos = 0;
+
+ if (d->len < (pos+4))
+ return NULL;
+ pos += 4;
+
+ return (struct atsc_ac3_descriptor*) d;
+}
+
+/**
+ * Retrieve pointer to additional_info field of a atsc_ac3_descriptor.
+ *
+ * @param d atsc_ac3_descriptor pointer.
+ * @return Pointer to additional_info field.
+ */
+static inline uint8_t *atsc_ac3_descriptor_additional_info(struct atsc_ac3_descriptor *d)
+{
+ int pos = sizeof(struct atsc_ac3_descriptor);
+
+ return ((uint8_t *) d) + pos;
+}
+
+/**
+ * Determine length of additional_info field of a atsc_ac3_descriptor.
+ *
+ * @param d atsc_ac3_descriptor pointer.
+ * @return Length of field in bytes.
+ */
+static inline int atsc_ac3_descriptor_additional_info_length(struct atsc_ac3_descriptor* d)
+{
+ return d->d.len - 3;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/atsc_text.c b/lib/libucsi/atsc/atsc_text.c
new file mode 100644
index 0000000..d79c83f
--- /dev/null
+++ b/lib/libucsi/atsc/atsc_text.c
@@ -0,0 +1,743 @@
+/*
+* section and descriptor parser
+*
+* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "libucsi/endianops.h"
+#include "libucsi/atsc/types.h"
+
+#define HUFFTREE_LITERAL_MASK 0x80
+#define HUFFSTRING_END 0x00
+#define HUFFSTRING_ESCAPE 0x1b
+
+#define DEST_ALLOC_DELTA 20
+
+struct hufftree_entry {
+ uint8_t left_idx;
+ uint8_t right_idx;
+} __ucsi_packed;
+
+struct huffbuff {
+ uint8_t *buf;
+ uint32_t buf_len;
+
+ uint32_t cur_byte;
+ uint8_t cur_bit;
+};
+
+
+static struct hufftree_entry program_description_hufftree[][128] = {
+ { {0x14, 0x15}, {0x9b, 0xd6}, {0xc9, 0xcf}, {0xd7, 0xc7}, {0x01, 0xa2},
+ {0xce, 0xcb}, {0x02, 0x03}, {0xc5, 0xcc}, {0xc6, 0xc8}, {0x04, 0xc4},
+ {0x05, 0xc2}, {0x06, 0xc3}, {0xd2, 0x07}, {0xd3, 0x08}, {0xca, 0xd4},
+ {0x09, 0xcd}, {0xd0, 0x0a}, {0xc1, 0x0b}, {0x0c, 0x0d}, {0x0e, 0x0f},
+ {0x10, 0x11}, {0x12, 0x13}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x38, 0x39}, {0xad, 0xaf}, {0xb7, 0xda}, {0xa8, 0xb3}, {0xb5, 0x01},
+ {0x02, 0x9b}, {0xb4, 0xf1}, {0xa2, 0xd5}, {0xd6, 0xd9}, {0x03, 0x04},
+ {0x05, 0xcf}, {0x06, 0xc9}, {0xf9, 0xea}, {0xeb, 0xf5}, {0xf6, 0x07},
+ {0x08, 0x09}, {0xb2, 0xc5}, {0xc6, 0xb1}, {0x0a, 0xee}, {0xcb, 0x0b},
+ {0xd4, 0x0c}, {0xc4, 0xc8}, {0xd2, 0x0d}, {0x0e, 0x0f}, {0xc7, 0xca},
+ {0xce, 0xd0}, {0xd7, 0x10}, {0xc2, 0x11}, {0xcc, 0xec}, {0xe5, 0xe7},
+ {0x12, 0xcd}, {0x13, 0x14}, {0xc3, 0x15}, {0x16, 0x17}, {0xed, 0x18},
+ {0x19, 0xf2}, {0x1a, 0xd3}, {0x1b, 0x1c}, {0xe4, 0x1d}, {0xc1, 0xe3},
+ {0x1e, 0xe9}, {0xf0, 0xe2}, {0xf7, 0x1f}, {0xf3, 0xe6}, {0x20, 0x21},
+ {0x22, 0xe8}, {0xef, 0x23}, {0x24, 0x25}, {0x26, 0x27}, {0x28, 0x29},
+ {0x2a, 0xf4}, {0x2b, 0x2c}, {0x2d, 0x2e}, {0x2f, 0xe1}, {0x30, 0x31},
+ {0x32, 0x33}, {0x34, 0x35}, {0x36, 0x37}, },
+ { {0x9b, 0x9b}, },
+ { {0x03, 0x04}, {0x80, 0xae}, {0xc8, 0xd4}, {0x01, 0x02}, {0x9b, 0xa0}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x02, 0xf3}, {0xa0, 0xf4}, {0x9b, 0x01}, },
+ { {0x9b, 0x9b}, },
+ { {0xac, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x01, 0xa0}, {0x9b, 0xa2}, },
+ { {0x07, 0x08}, {0xe2, 0xe4}, {0xe5, 0xe6}, {0xa0, 0xf2}, {0xe1, 0x01},
+ {0x02, 0xf3}, {0xe3, 0x03}, {0x04, 0x05}, {0x9b, 0x06}, },
+ { {0x04, 0x80}, {0xca, 0xd3}, {0xa2, 0x01}, {0x9b, 0x02}, {0x03, 0xa0}, },
+ { {0x9b, 0xa0}, },
+ { {0x03, 0x04}, {0x9b, 0xb7}, {0xf4, 0xa0}, {0xb0, 0xf3}, {0x01, 0x02}, },
+ { {0xb9, 0x02}, {0xb8, 0x9b}, {0xa0, 0x01}, },
+ { {0xae, 0x02}, {0xb6, 0x9b}, {0x01, 0xa0}, },
+ { {0xa0, 0x01}, {0x9b, 0xb0}, },
+ { {0xae, 0x01}, {0x9b, 0xa0}, },
+ { {0xae, 0x01}, {0xa0, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x01}, {0xac, 0xae}, },
+ { {0x9b, 0x9b}, },
+ { {0x02, 0x03}, {0x9b, 0xa0}, {0xb5, 0xb6}, {0xb8, 0x01}, },
+ { {0x9b, 0xa0}, },
+ { {0x9b, 0xa0}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0xa0}, },
+ { {0x9b, 0x9b}, },
+ { {0x08, 0x09}, {0xe6, 0xf5}, {0xf3, 0xf4}, {0x9b, 0xe4}, {0x01, 0xed},
+ {0x02, 0x03}, {0x04, 0xf2}, {0x05, 0x06}, {0xec, 0xee}, {0x07, 0xa0}, },
+ { {0x05, 0x06}, {0x9b, 0xec}, {0xf5, 0x01}, {0x02, 0xe1}, {0xef, 0xe5},
+ {0xe9, 0xf2}, {0x03, 0x04}, },
+ { {0x06, 0x07}, {0x9b, 0xe9}, {0xf9, 0xf2}, {0xf5, 0x01}, {0x02, 0x03},
+ {0xec, 0xef}, {0xe1, 0x04}, {0xe8, 0x05}, },
+ { {0x05, 0x06}, {0xf9, 0xf2}, {0xf5, 0x9b}, {0xe5, 0xef}, {0x01, 0x02},
+ {0xe9, 0xe1}, {0x03, 0x04}, },
+ { {0x06, 0x07}, {0xe1, 0xe9}, {0xee, 0xf6}, {0xe4, 0xec}, {0xf3, 0x01},
+ {0x02, 0xf2}, {0x03, 0x04}, {0x9b, 0x05}, },
+ { {0x02, 0x03}, {0xe5, 0xec}, {0x9b, 0xef}, {0x01, 0xf2}, },
+ { {0x05, 0x06}, {0xf5, 0xef}, {0x9b, 0xec}, {0xe9, 0x01}, {0xe1, 0xf2},
+ {0x02, 0xe5}, {0x03, 0x04}, },
+ { {0x03, 0x04}, {0x9b, 0xe5}, {0xe9, 0xf5}, {0xe1, 0x01}, {0xef, 0x02}, },
+ { {0x04, 0x05}, {0xa0, 0xc9}, {0xf3, 0x9b}, {0xae, 0xf2}, {0x01, 0x02},
+ {0x03, 0xee}, },
+ { {0xef, 0x05}, {0x9b, 0xae}, {0xe9, 0xe5}, {0x01, 0xf5}, {0x02, 0xe1},
+ {0x03, 0x04}, },
+ { {0xe5, 0x03}, {0xe1, 0xe9}, {0xf2, 0x9b}, {0x01, 0x02}, },
+ { {0x03, 0x04}, {0x9b, 0xe9}, {0xf5, 0x01}, {0xe5, 0x02}, {0xef, 0xe1}, },
+ { {0xe1, 0x05}, {0x9b, 0xe3}, {0xef, 0x01}, {0xf5, 0xe5}, {0x02, 0x03},
+ {0xe9, 0x04}, },
+ { {0xe5, 0x03}, {0x9b, 0xe9}, {0x01, 0xe1}, {0xef, 0x02}, },
+ { {0x03, 0x04}, {0xa7, 0xee}, {0xec, 0xf2}, {0xf3, 0x01}, {0x9b, 0x02}, },
+ { {0xe1, 0x06}, {0x9b, 0xe8}, {0xe9, 0x01}, {0xf2, 0xec}, {0x02, 0xef},
+ {0x03, 0xe5}, {0x04, 0x05}, },
+ { {0x9b, 0x9b}, },
+ { {0x03, 0x04}, {0x9b, 0xae}, {0x01, 0xe9}, {0x02, 0xe1}, {0xe5, 0xef}, },
+ { {0x09, 0x0a}, {0xf6, 0xf9}, {0x01, 0xae}, {0xe3, 0xe9}, {0xf5, 0x9b},
+ {0xe5, 0xef}, {0x02, 0x03}, {0xe1, 0x04}, {0xe8, 0x05}, {0x06, 0xf4},
+ {0x07, 0x08}, },
+ { {0xe8, 0x07}, {0xe5, 0xf7}, {0xd6, 0xe1}, {0x9b, 0xe9}, {0xf2, 0x01},
+ {0x02, 0x03}, {0x04, 0xef}, {0x05, 0x06}, },
+ { {0xae, 0x01}, {0x9b, 0xee}, },
+ { {0xe9, 0x02}, {0xe5, 0x9b}, {0xa0, 0x01}, },
+ { {0x03, 0x04}, {0x9b, 0xe8}, {0xe5, 0xe1}, {0xef, 0x01}, {0xe9, 0x02}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0xef}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x18, 0x19}, {0xe8, 0xef}, {0xf8, 0x9b}, {0xa7, 0xf7}, {0xfa, 0x01},
+ {0x02, 0x03}, {0x04, 0xe5}, {0xae, 0x05}, {0xe6, 0xe2}, {0x06, 0xf6},
+ {0xeb, 0xf5}, {0xe9, 0x07}, {0xf0, 0xf9}, {0xe7, 0x08}, {0x09, 0xe4},
+ {0x0a, 0xe3}, {0x0b, 0xed}, {0x0c, 0xf3}, {0x0d, 0x0e}, {0x0f, 0xec},
+ {0x10, 0xf4}, {0x11, 0x12}, {0xf2, 0xa0}, {0x13, 0x14}, {0x15, 0xee},
+ {0x16, 0x17}, },
+ { {0x0b, 0x0c}, {0xe4, 0xf3}, {0x9b, 0xae}, {0xe2, 0x01}, {0x02, 0x03},
+ {0xec, 0xa0}, {0x04, 0xe9}, {0xf2, 0xf5}, {0x05, 0xf9}, {0xe1, 0x06},
+ {0xef, 0x07}, {0xe5, 0x08}, {0x09, 0x0a}, },
+ { {0x0f, 0x10}, {0xf1, 0xae}, {0xc4, 0xf9}, {0xac, 0x01}, {0xe3, 0x02},
+ {0x9b, 0xf2}, {0x03, 0x04}, {0xa0, 0xec}, {0xf5, 0x05}, {0x06, 0xe9},
+ {0x07, 0xeb}, {0x08, 0xf4}, {0x09, 0xe5}, {0x0a, 0xef}, {0xe1, 0xe8},
+ {0x0b, 0x0c}, {0x0d, 0x0e}, },
+ { {0x13, 0x14}, {0xa7, 0xbb}, {0xe6, 0xed}, {0xf7, 0xe7}, {0xf6, 0x01},
+ {0x02, 0x9b}, {0xee, 0x03}, {0x04, 0xec}, {0x05, 0xf5}, {0x06, 0xac},
+ {0xe4, 0xf9}, {0xf2, 0x07}, {0x08, 0x09}, {0xae, 0x0a}, {0xef, 0x0b},
+ {0xe1, 0xf3}, {0x0c, 0xe9}, {0x0d, 0x0e}, {0x0f, 0x10}, {0xe5, 0x11},
+ {0x12, 0xa0}, },
+ { {0x1d, 0x1e}, {0xa9, 0xe8}, {0xf5, 0x9b}, {0x01, 0xad}, {0xbb, 0xeb},
+ {0xfa, 0x02}, {0xa7, 0xe6}, {0xe2, 0xe7}, {0x03, 0x04}, {0x05, 0x06},
+ {0xe9, 0xf8}, {0x07, 0xac}, {0xef, 0xf0}, {0x08, 0xed}, {0xf6, 0xf9},
+ {0x09, 0xf7}, {0x0a, 0x0b}, {0xae, 0x0c}, {0xe3, 0x0d}, {0xe5, 0xf4},
+ {0x0e, 0x0f}, {0xe4, 0x10}, {0xec, 0x11}, {0xe1, 0x12}, {0x13, 0x14},
+ {0x15, 0x16}, {0xee, 0xf3}, {0x17, 0x18}, {0xf2, 0xa0}, {0x19, 0x1a},
+ {0x1b, 0x1c}, },
+ { {0x09, 0x0a}, {0xae, 0x9b}, {0xec, 0x01}, {0xf5, 0x02}, {0xf4, 0xe6},
+ {0x03, 0xe1}, {0xe5, 0xe9}, {0x04, 0xf2}, {0xef, 0x05}, {0x06, 0x07},
+ {0xa0, 0x08}, },
+ { {0x0e, 0x0f}, {0xad, 0xe7}, {0x9b, 0xa7}, {0xf9, 0x01}, {0xec, 0x02},
+ {0xac, 0xf2}, {0x03, 0xae}, {0xf3, 0xf5}, {0x04, 0x05}, {0xef, 0x06},
+ {0x07, 0xe9}, {0xe1, 0x08}, {0x09, 0xe8}, {0x0a, 0x0b}, {0xe5, 0x0c},
+ {0xa0, 0x0d}, },
+ { {0x0d, 0x0e}, {0xa7, 0xac}, {0xf3, 0xad}, {0x01, 0x02}, {0x9b, 0xf9},
+ {0xf5, 0xae}, {0x03, 0xee}, {0x04, 0xf2}, {0x05, 0x06}, {0xf4, 0x07},
+ {0x08, 0x09}, {0xef, 0xe1}, {0xa0, 0x0a}, {0xe9, 0x0b}, {0x0c, 0xe5}, },
+ { {0x14, 0x15}, {0xac, 0xe2}, {0xf8, 0x9b}, {0xae, 0xfa}, {0x01, 0xeb},
+ {0x02, 0xa0}, {0x03, 0x04}, {0xf0, 0x05}, {0x06, 0xe6}, {0xf6, 0x07},
+ {0xe4, 0xed}, {0xe7, 0x08}, {0xe1, 0xef}, {0xf2, 0x09}, {0x0a, 0x0b},
+ {0xec, 0x0c}, {0xe5, 0xe3}, {0x0d, 0xf4}, {0x0e, 0xf3}, {0x0f, 0x10},
+ {0x11, 0xee}, {0x12, 0x13}, },
+ { {0x03, 0xef}, {0x9b, 0xe1}, {0xe5, 0xf5}, {0x01, 0x02}, },
+ { {0x08, 0x09}, {0xec, 0xf9}, {0xa7, 0xee}, {0x01, 0xac}, {0x9b, 0xae},
+ {0x02, 0x03}, {0x04, 0xf3}, {0x05, 0xe9}, {0x06, 0xa0}, {0x07, 0xe5}, },
+ { {0x16, 0x17}, {0xa7, 0xad}, {0xee, 0xe3}, {0xeb, 0xf2}, {0x9b, 0xe2},
+ {0x01, 0x02}, {0xf5, 0x03}, {0xf4, 0xac}, {0x04, 0x05}, {0xe6, 0xed},
+ {0xf6, 0x06}, {0xae, 0xf0}, {0x07, 0x08}, {0xf3, 0x09}, {0x0a, 0xe4},
+ {0x0b, 0x0c}, {0xf9, 0x0d}, {0xef, 0x0e}, {0xe1, 0x0f}, {0x10, 0xe9},
+ {0xec, 0x11}, {0xa0, 0xe5}, {0x12, 0x13}, {0x14, 0x15}, },
+ { {0x0c, 0x0d}, {0xa7, 0xbb}, {0x9b, 0x01}, {0xf9, 0xae}, {0xe2, 0x02},
+ {0xed, 0xf3}, {0x03, 0xf5}, {0xef, 0xf0}, {0x04, 0x05}, {0xe9, 0x06},
+ {0x07, 0x08}, {0x09, 0xa0}, {0xe1, 0xe5}, {0x0a, 0x0b}, },
+ { {0x19, 0x1a}, {0xad, 0xbb}, {0xe2, 0xea}, {0xed, 0xf2}, {0xfa, 0xe6},
+ {0xec, 0x01}, {0x02, 0x03}, {0x9b, 0xf5}, {0x04, 0xa7}, {0xf6, 0xf9},
+ {0x05, 0x06}, {0xeb, 0xef}, {0x07, 0x08}, {0x09, 0x0a}, {0xac, 0x0b},
+ {0x0c, 0xe3}, {0xae, 0x0d}, {0xee, 0xe9}, {0x0e, 0xe1}, {0x0f, 0xf3},
+ {0x10, 0x11}, {0xf4, 0x12}, {0xe7, 0xe5}, {0x13, 0x14}, {0xe4, 0x15},
+ {0x16, 0x17}, {0xa0, 0x18}, },
+ { {0x1a, 0x1b}, {0xc2, 0x9b}, {0xad, 0xac}, {0xf8, 0x01}, {0xae, 0x02},
+ {0x03, 0xe5}, {0xe7, 0xe8}, {0xf9, 0xe9}, {0xeb, 0x04}, {0xe3, 0xe1},
+ {0x05, 0xf6}, {0x06, 0xe4}, {0x07, 0xe2}, {0xf0, 0x08}, {0x09, 0xf3},
+ {0xf4, 0xf7}, {0xef, 0x0a}, {0x0b, 0x0c}, {0x0d, 0xec}, {0x0e, 0x0f},
+ {0x10, 0xf5}, {0xed, 0x11}, {0xe6, 0xa0}, {0x12, 0xf2}, {0x13, 0x14},
+ {0x15, 0xee}, {0x16, 0x17}, {0x18, 0x19}, },
+ { {0x0e, 0x0f}, {0xad, 0xed}, {0xf9, 0x9b}, {0xae, 0x01}, {0xf3, 0x02},
+ {0x03, 0xf5}, {0xf4, 0xf0}, {0x04, 0xef}, {0x05, 0xe9}, {0x06, 0xe8},
+ {0xa0, 0xe1}, {0xec, 0x07}, {0xf2, 0x08}, {0xe5, 0x09}, {0x0a, 0x0b},
+ {0x0c, 0x0d}, },
+ { {0x9b, 0xf5}, },
+ { {0x19, 0x1a}, {0xa9, 0xbb}, {0xf6, 0xe6}, {0x01, 0x9b}, {0xad, 0xe2},
+ {0xf0, 0x02}, {0xa7, 0x03}, {0x04, 0x05}, {0xf5, 0xe3}, {0xac, 0xe7},
+ {0xf2, 0x06}, {0xeb, 0x07}, {0xec, 0xed}, {0xee, 0xf9}, {0x08, 0xae},
+ {0x09, 0x0a}, {0xe4, 0x0b}, {0x0c, 0xf4}, {0x0d, 0xf3}, {0x0e, 0x0f},
+ {0x10, 0xe1}, {0xef, 0x11}, {0xe9, 0x12}, {0x13, 0xe5}, {0x14, 0xa0},
+ {0x15, 0x16}, {0x17, 0x18}, },
+ { {0xa0, 0x16}, {0xa2, 0xa7}, {0xe2, 0xeb}, {0xed, 0xee}, {0x9b, 0xf7},
+ {0x01, 0x02}, {0x03, 0xbb}, {0xf9, 0xf0}, {0x04, 0x05}, {0xec, 0x06},
+ {0x07, 0x08}, {0xf5, 0xe1}, {0x09, 0xac}, {0xe3, 0x0a}, {0xe8, 0x0b},
+ {0xe9, 0x0c}, {0xef, 0xf3}, {0xae, 0x0d}, {0x0e, 0xe5}, {0x0f, 0x10},
+ {0x11, 0xf4}, {0x12, 0x13}, {0x14, 0x15}, },
+ { {0x14, 0x15}, {0xbb, 0xe2}, {0xad, 0xed}, {0x01, 0x9b}, {0xa7, 0xe3},
+ {0xac, 0xec}, {0xee, 0x02}, {0xf7, 0x03}, {0x04, 0xf9}, {0x05, 0x06},
+ {0x07, 0x08}, {0xf4, 0xae}, {0xf5, 0x09}, {0x0a, 0xf2}, {0xe1, 0xf3},
+ {0x0b, 0x0c}, {0x0d, 0xe9}, {0x0e, 0x0f}, {0xef, 0xe5}, {0x10, 0xa0},
+ {0xe8, 0x11}, {0x12, 0x13}, },
+ { {0x11, 0x12}, {0xef, 0xf6}, {0x9b, 0xeb}, {0xf9, 0x01}, {0xa0, 0xe2},
+ {0x02, 0xe1}, {0x03, 0xed}, {0x04, 0xe3}, {0xe9, 0x05}, {0xe4, 0xe5},
+ {0xe7, 0x06}, {0xec, 0xf0}, {0x07, 0x08}, {0x09, 0x0a}, {0x0b, 0xf3},
+ {0x0c, 0xf4}, {0xee, 0x0d}, {0xf2, 0x0e}, {0x0f, 0x10}, },
+ { {0x05, 0xe5}, {0xf3, 0xf9}, {0x9b, 0x01}, {0xef, 0x02}, {0x03, 0xe1},
+ {0x04, 0xe9}, },
+ { {0x0a, 0x0b}, {0xae, 0x9b}, {0xec, 0xed}, {0x01, 0x02}, {0xf3, 0xee},
+ {0xf2, 0x03}, {0xe5, 0x04}, {0xe8, 0xa0}, {0xe1, 0x05}, {0xef, 0x06},
+ {0x07, 0x08}, {0xe9, 0x09}, },
+ { {0x05, 0x06}, {0xa0, 0xac}, {0xad, 0xf4}, {0xe9, 0x01}, {0x02, 0xe1},
+ {0xe5, 0x03}, {0x9b, 0x04}, },
+ { {0x11, 0xa0}, {0xbf, 0xe1}, {0xe2, 0xe6}, {0xed, 0xe4}, {0xe9, 0xf7},
+ {0xa7, 0x01}, {0x02, 0xbb}, {0x03, 0x04}, {0xec, 0x05}, {0x9b, 0xee},
+ {0x06, 0xef}, {0x07, 0xac}, {0xe5, 0xf3}, {0x08, 0x09}, {0x0a, 0xae},
+ {0x0b, 0x0c}, {0x0d, 0x0e}, {0x0f, 0x10}, },
+ { {0x06, 0x07}, {0xa0, 0xae}, {0xe1, 0xe5}, {0xec, 0xfa}, {0x9b, 0xef},
+ {0xe9, 0x01}, {0x02, 0x03}, {0x04, 0x05}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+};
+
+static struct hufftree_entry program_title_hufftree[][128] = {
+ { {0x1b, 0x1c}, {0xb4, 0xa4}, {0xb2, 0xb7}, {0xda, 0x01}, {0xd1, 0x02},
+ {0x03, 0x9b}, {0x04, 0xd5}, {0xd9, 0x05}, {0xcb, 0xd6}, {0x06, 0xcf},
+ {0x07, 0x08}, {0xca, 0x09}, {0xc9, 0xc5}, {0xc6, 0x0a}, {0xd2, 0xc4},
+ {0xc7, 0xcc}, {0xd0, 0xc8}, {0xd7, 0xce}, {0x0b, 0xc1}, {0x0c, 0xc2},
+ {0xcd, 0xc3}, {0x0d, 0x0e}, {0x0f, 0x10}, {0xd3, 0x11}, {0xd4, 0x12},
+ {0x13, 0x14}, {0x15, 0x16}, {0x17, 0x18}, {0x19, 0x1a}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x29, 0x2a}, {0xd8, 0xe5}, {0xb9, 0x01}, {0xa7, 0xb1}, {0xec, 0xd1},
+ {0x02, 0xad}, {0xb2, 0xda}, {0xe3, 0xb3}, {0x03, 0xe4}, {0xe6, 0x04},
+ {0x9b, 0xe2}, {0x05, 0x06}, {0x07, 0x08}, {0x09, 0xd5}, {0x0a, 0xd6},
+ {0x0b, 0xd9}, {0x0c, 0xa6}, {0xe9, 0xcb}, {0xc5, 0xcf}, {0x0d, 0x0e},
+ {0xca, 0xc9}, {0x0f, 0xc7}, {0x10, 0x11}, {0xe1, 0x12}, {0x13, 0xc6},
+ {0xd2, 0xc8}, {0xce, 0xc1}, {0xc4, 0xd0}, {0xcc, 0x14}, {0x15, 0xef},
+ {0xc2, 0xd7}, {0x16, 0xcd}, {0x17, 0xf4}, {0xd4, 0x18}, {0x19, 0x1a},
+ {0xc3, 0xd3}, {0x1b, 0x1c}, {0x1d, 0x1e}, {0x1f, 0x20}, {0x21, 0x22},
+ {0x23, 0x24}, {0x25, 0x26}, {0x27, 0x28}, },
+ { {0x01, 0x80}, {0xa0, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0xb1, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0xa0}, },
+ { {0x04, 0xf3}, {0xe4, 0xb9}, {0x01, 0xf4}, {0xa0, 0x9b}, {0x02, 0x03}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x01, 0x02}, {0x9b, 0xc1}, {0xc8, 0xd3}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0xa0}, },
+ { {0x07, 0x08}, {0xb1, 0xd2}, {0xd3, 0xd4}, {0xd5, 0xad}, {0xcd, 0xc1},
+ {0x01, 0x02}, {0x03, 0xa0}, {0x04, 0x9b}, {0x05, 0x06}, },
+ { {0xa0, 0x05}, {0xc9, 0xd7}, {0xd3, 0x01}, {0x02, 0x9b}, {0xae, 0x80},
+ {0x03, 0x04}, },
+ { {0x9b, 0x9b}, },
+ { {0x02, 0x03}, {0xad, 0x9b}, {0x01, 0x80}, {0xa0, 0xb0}, },
+ { {0x04, 0x05}, {0x80, 0x9b}, {0xb1, 0xb2}, {0xa0, 0xb0}, {0xb9, 0x01},
+ {0x02, 0x03}, },
+ { {0x02, 0x03}, {0xb1, 0xba}, {0x01, 0xb0}, {0x9b, 0x80}, },
+ { {0x80, 0x01}, {0xb0, 0x9b}, },
+ { {0x9b, 0xb8}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0xb0}, },
+ { {0x9b, 0xa0}, },
+ { {0x02, 0x03}, {0xb1, 0xb3}, {0xb9, 0xb0}, {0x01, 0x9b}, },
+ { {0x9b, 0xa0}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x80}, },
+ { {0x9b, 0x9b}, },
+ { {0x13, 0x14}, {0xaa, 0xad}, {0xae, 0xf6}, {0xe7, 0xf4}, {0xe2, 0xe9},
+ {0x01, 0x02}, {0xc2, 0xf0}, {0x9b, 0xf3}, {0xe3, 0xe6}, {0xf7, 0x03},
+ {0xf5, 0x04}, {0x05, 0x06}, {0xf2, 0x07}, {0x08, 0x09}, {0x0a, 0x0b},
+ {0x0c, 0xe4}, {0xa0, 0x0d}, {0xec, 0xee}, {0x0e, 0xed}, {0x0f, 0x10},
+ {0x11, 0x12}, },
+ { {0x08, 0x09}, {0xc1, 0xd3}, {0x9b, 0x01}, {0xc3, 0x02}, {0xe9, 0xec},
+ {0x03, 0xf2}, {0xf5, 0x04}, {0xef, 0xe1}, {0x05, 0xe5}, {0x06, 0x07}, },
+ { {0x0b, 0x0c}, {0xc1, 0xf9}, {0x01, 0xc2}, {0xcf, 0xe5}, {0xf5, 0x9b},
+ {0xe9, 0x02}, {0xa0, 0x03}, {0x04, 0x05}, {0xf2, 0x06}, {0xec, 0x07},
+ {0xe1, 0x08}, {0x09, 0xe8}, {0x0a, 0xef}, },
+ { {0x05, 0x06}, {0xf9, 0x9b}, {0x01, 0xf5}, {0x02, 0xf2}, {0xe9, 0xe5},
+ {0xef, 0x03}, {0xe1, 0x04}, },
+ { {0x0a, 0x0b}, {0xf1, 0xf5}, {0xf3, 0x01}, {0xed, 0xf9}, {0xc3, 0x02},
+ {0xec, 0xee}, {0xe4, 0xf8}, {0x03, 0x9b}, {0xf6, 0x04}, {0x05, 0xe1},
+ {0x06, 0x07}, {0x08, 0x09}, },
+ { {0x07, 0x08}, {0xa0, 0x9b}, {0xcc, 0x01}, {0xe5, 0x02}, {0xec, 0xf5},
+ {0xef, 0x03}, {0xe9, 0xf2}, {0x04, 0x05}, {0xe1, 0x06}, },
+ { {0x09, 0x0a}, {0xae, 0xec}, {0xf9, 0xc1}, {0xe8, 0x01}, {0x9b, 0x02},
+ {0x03, 0x04}, {0xe1, 0xf5}, {0xe9, 0x05}, {0xe5, 0x06}, {0xf2, 0xef},
+ {0x07, 0x08}, },
+ { {0xef, 0x05}, {0x80, 0x9b}, {0xf5, 0x01}, {0x02, 0xe9}, {0xe1, 0x03},
+ {0xe5, 0x04}, },
+ { {0xee, 0x0b}, {0xba, 0xd4}, {0xae, 0xf2}, {0xe3, 0x01}, {0xa0, 0x02},
+ {0x80, 0x9b}, {0xed, 0x03}, {0xc9, 0xf3}, {0xf4, 0x04}, {0x05, 0x06},
+ {0x07, 0x08}, {0x09, 0x0a}, },
+ { {0x02, 0x03}, {0x9b, 0xf5}, {0x01, 0xe1}, {0xef, 0xe5}, },
+ { {0x05, 0xe9}, {0xe1, 0xef}, {0xf5, 0xee}, {0x9b, 0xe5}, {0x01, 0x02},
+ {0x03, 0x04}, },
+ { {0x04, 0x05}, {0xa0, 0x9b}, {0x01, 0xf5}, {0x02, 0xe5}, {0xef, 0x03},
+ {0xe1, 0xe9}, },
+ { {0x08, 0x09}, {0xaa, 0xd4}, {0x01, 0x9b}, {0xe3, 0x02}, {0xf2, 0x03},
+ {0xe5, 0x04}, {0xf5, 0xf9}, {0xe9, 0x05}, {0xef, 0x06}, {0x07, 0xe1}, },
+ { {0xe5, 0x08}, {0xce, 0xa0}, {0xc6, 0xf5}, {0x01, 0x02}, {0x9b, 0xc2},
+ {0x03, 0xe1}, {0x04, 0xef}, {0x05, 0xe9}, {0x06, 0x07}, },
+ { {0x09, 0x0a}, {0xe4, 0xf3}, {0xe6, 0xf6}, {0xf7, 0xf0}, {0xf2, 0x01},
+ {0xec, 0x02}, {0x03, 0xa0}, {0x9b, 0x04}, {0x05, 0xf5}, {0x06, 0x07},
+ {0xee, 0x08}, },
+ { {0x0b, 0x0c}, {0xa0, 0xf3}, {0xf9, 0xae}, {0xd2, 0xc7}, {0x01, 0x9b},
+ {0x02, 0xf5}, {0x03, 0x04}, {0x05, 0xe9}, {0xec, 0x06}, {0xe5, 0x07},
+ {0xef, 0x08}, {0xe1, 0x09}, {0xf2, 0x0a}, },
+ { {0x01, 0xf5}, {0x9b, 0xd6}, },
+ { {0x04, 0x05}, {0xe8, 0x9b}, {0x01, 0xf5}, {0x02, 0xe1}, {0xe9, 0xef},
+ {0x03, 0xe5}, },
+ { {0x10, 0x11}, {0xaa, 0xec}, {0xf1, 0xae}, {0xa0, 0xf7}, {0xed, 0xee},
+ {0x01, 0x02}, {0x9b, 0xeb}, {0x03, 0x04}, {0x05, 0x06}, {0xe3, 0x07},
+ {0xef, 0x08}, {0xe9, 0xf5}, {0x09, 0xe1}, {0xe5, 0xf0}, {0xe8, 0x0a},
+ {0x0b, 0x0c}, {0x0d, 0xf4}, {0x0e, 0x0f}, },
+ { {0xe8, 0x0a}, {0xad, 0xce}, {0x9b, 0x01}, {0xd6, 0x02}, {0xf5, 0xf7},
+ {0x03, 0x04}, {0xe1, 0xe5}, {0xe9, 0x05}, {0xf2, 0x06}, {0xef, 0x07},
+ {0x08, 0x09}, },
+ { {0xee, 0x03}, {0xec, 0xae}, {0x01, 0x9b}, {0x02, 0xf0}, },
+ { {0x06, 0xe9}, {0xa0, 0xc3}, {0xef, 0x9b}, {0xe5, 0x01}, {0x80, 0x02},
+ {0x03, 0xe1}, {0x04, 0x05}, },
+ { {0x06, 0x07}, {0xc6, 0xd7}, {0x01, 0x9b}, {0xf2, 0x02}, {0x03, 0xe8},
+ {0xe5, 0xe1}, {0x04, 0xe9}, {0xef, 0x05}, },
+ { {0x9b, 0x9b}, },
+ { {0x02, 0xef}, {0xe1, 0x9b}, {0x01, 0xe5}, },
+ { {0x01, 0xef}, {0x9b, 0xe1}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x19, 0x1a}, {0x9b, 0xba}, {0xe5, 0xea}, {0xf8, 0x01}, {0x02, 0xe6},
+ {0xa7, 0x03}, {0xfa, 0xe8}, {0x04, 0xf7}, {0x05, 0xf5}, {0xe2, 0x06},
+ {0xeb, 0x07}, {0xf0, 0x08}, {0x80, 0xf6}, {0xe7, 0x09}, {0xe4, 0x0a},
+ {0xa0, 0xe9}, {0x0b, 0xe3}, {0xf9, 0x0c}, {0x0d, 0xed}, {0x0e, 0x0f},
+ {0xf3, 0x10}, {0x11, 0xec}, {0x12, 0xf4}, {0xf2, 0x13}, {0xee, 0x14},
+ {0x15, 0x16}, {0x17, 0x18}, },
+ { {0x0a, 0x0b}, {0xf3, 0x9b}, {0xf5, 0xe2}, {0x01, 0x80}, {0xa0, 0x02},
+ {0xe5, 0xf2}, {0xe9, 0x03}, {0xec, 0x04}, {0xf9, 0x05}, {0xef, 0x06},
+ {0xe1, 0x07}, {0x08, 0x09}, },
+ { {0x10, 0x11}, {0xc3, 0xcc}, {0xc7, 0x9b}, {0xe3, 0x01}, {0x80, 0xec},
+ {0xf9, 0x02}, {0xf3, 0x03}, {0xf5, 0x04}, {0x05, 0xf2}, {0x06, 0xe9},
+ {0xa0, 0x07}, {0x08, 0xef}, {0xf4, 0x09}, {0x0a, 0xe1}, {0x0b, 0xe8},
+ {0xeb, 0xe5}, {0x0c, 0x0d}, {0x0e, 0x0f}, },
+ { {0x0e, 0x0f}, {0xae, 0xf5}, {0xf7, 0x01}, {0xec, 0x02}, {0xe4, 0xe7},
+ {0xf2, 0x03}, {0x9b, 0xef}, {0x04, 0xf6}, {0x05, 0x06}, {0xf9, 0xf3},
+ {0x07, 0xe9}, {0xe1, 0x08}, {0x09, 0x80}, {0x0a, 0x0b}, {0xe5, 0x0c},
+ {0x0d, 0xa0}, },
+ { {0x1e, 0x1f}, {0x9b, 0xa1}, {0xad, 0xe8}, {0xea, 0xf1}, {0xf5, 0xfa},
+ {0x01, 0x02}, {0x03, 0x04}, {0xba, 0xf8}, {0xa7, 0xe2}, {0xe9, 0x05},
+ {0x06, 0x07}, {0xe6, 0xed}, {0xe7, 0xeb}, {0x08, 0x09}, {0xf6, 0xf0},
+ {0x0a, 0xef}, {0x0b, 0xe3}, {0x0c, 0x0d}, {0x0e, 0xf9}, {0x0f, 0xe4},
+ {0xec, 0x10}, {0xe5, 0x11}, {0xf4, 0xf7}, {0x12, 0x13}, {0xe1, 0x14},
+ {0x15, 0x16}, {0xee, 0xf3}, {0x17, 0x80}, {0x18, 0x19}, {0xf2, 0x1a},
+ {0x1b, 0xa0}, {0x1c, 0x1d}, },
+ { {0xa0, 0x0b}, {0xf5, 0x9b}, {0x01, 0xec}, {0xf3, 0xf2}, {0x80, 0xe1},
+ {0x02, 0x03}, {0xf4, 0xe9}, {0xef, 0xe6}, {0x04, 0x05}, {0x06, 0x07},
+ {0xe5, 0x08}, {0x09, 0x0a}, },
+ { {0x0f, 0x10}, {0xba, 0xf9}, {0xa7, 0xf4}, {0x9b, 0x01}, {0xe7, 0xec},
+ {0x02, 0xee}, {0x03, 0xef}, {0xf5, 0x04}, {0xf2, 0x05}, {0x06, 0xe9},
+ {0x07, 0xf3}, {0xe1, 0x08}, {0x09, 0x0a}, {0x0b, 0xe5}, {0x80, 0x0c},
+ {0xe8, 0xa0}, {0x0d, 0x0e}, },
+ { {0xe5, 0x0d}, {0xe2, 0xf5}, {0xf7, 0x9b}, {0xec, 0x01}, {0xf9, 0xee},
+ {0x02, 0x03}, {0x04, 0xf2}, {0x05, 0x80}, {0x06, 0xa0}, {0xe1, 0xef},
+ {0x07, 0xf4}, {0xe9, 0x08}, {0x09, 0x0a}, {0x0b, 0x0c}, },
+ { {0x15, 0x16}, {0xa1, 0xf8}, {0xe9, 0xeb}, {0x01, 0x80}, {0x9b, 0xfa},
+ {0xe2, 0x02}, {0x03, 0x04}, {0xa0, 0xf0}, {0x05, 0x06}, {0x07, 0xe1},
+ {0x08, 0xe6}, {0xf2, 0xed}, {0xf6, 0x09}, {0xe4, 0x0a}, {0xef, 0xf4},
+ {0xec, 0xf3}, {0xe7, 0xe5}, {0x0b, 0xe3}, {0x0c, 0x0d}, {0x0e, 0x0f},
+ {0x10, 0x11}, {0x12, 0x13}, {0xee, 0x14}, },
+ { {0xef, 0x01}, {0x9b, 0xe1}, },
+ { {0x0b, 0x0c}, {0xd4, 0xef}, {0xe6, 0xec}, {0xf7, 0xe1}, {0x01, 0xba},
+ {0x02, 0x9b}, {0xf9, 0x03}, {0x04, 0x05}, {0xf3, 0x06}, {0x07, 0x08},
+ {0xe9, 0xa0}, {0x09, 0x80}, {0xe5, 0x0a}, },
+ { {0x15, 0x16}, {0xa7, 0xba}, {0xe3, 0xf7}, {0xf2, 0xad}, {0xe2, 0x01},
+ {0x02, 0x9b}, {0xe6, 0x03}, {0xed, 0xf6}, {0x04, 0xeb}, {0x05, 0xf4},
+ {0x06, 0x07}, {0x08, 0xf3}, {0x09, 0xf5}, {0x0a, 0xef}, {0x0b, 0x0c},
+ {0x80, 0xf9}, {0xe1, 0x0d}, {0xe4, 0xe9}, {0xa0, 0x0e}, {0x0f, 0xec},
+ {0xe5, 0x10}, {0x11, 0x12}, {0x13, 0x14}, },
+ { {0x0a, 0x0b}, {0xf9, 0x9b}, {0xf5, 0xf3}, {0x01, 0x02}, {0xe2, 0xed},
+ {0x80, 0x03}, {0xf0, 0xef}, {0x04, 0xa0}, {0x05, 0xe9}, {0x06, 0xe1},
+ {0x07, 0x08}, {0x09, 0xe5}, },
+ { {0x18, 0x19}, {0xe2, 0xea}, {0xf2, 0xe8}, {0xec, 0xed}, {0xfa, 0x9b},
+ {0x01, 0xf5}, {0x02, 0x03}, {0xf6, 0x04}, {0xba, 0xe6}, {0x05, 0x06},
+ {0xeb, 0xef}, {0x07, 0xa7}, {0xf9, 0x08}, {0x09, 0x0a}, {0x0b, 0xe3},
+ {0x0c, 0xee}, {0xe1, 0x0d}, {0xf3, 0x0e}, {0xe9, 0x0f}, {0x10, 0xf4},
+ {0x80, 0xe4}, {0xe5, 0x11}, {0x12, 0xe7}, {0xa0, 0x13}, {0x14, 0x15},
+ {0x16, 0x17}, },
+ { {0x1b, 0x1c}, {0xae, 0xfa}, {0xbf, 0x01}, {0xa7, 0x9b}, {0x02, 0xe9},
+ {0xf8, 0xf9}, {0x03, 0xe5}, {0xe8, 0x04}, {0xe1, 0xeb}, {0x05, 0xe2},
+ {0x06, 0x07}, {0xe3, 0x08}, {0xe7, 0xf4}, {0x09, 0x80}, {0xf6, 0xf0},
+ {0x0a, 0xe4}, {0x0b, 0xf3}, {0xf7, 0x0c}, {0x0d, 0xef}, {0xec, 0xa0},
+ {0x0e, 0x0f}, {0xed, 0xe6}, {0x10, 0xf5}, {0x11, 0x12}, {0x13, 0x14},
+ {0x15, 0xf2}, {0x16, 0xee}, {0x17, 0x18}, {0x19, 0x1a}, },
+ { {0x0e, 0x0f}, {0xed, 0xa7}, {0x9b, 0xe4}, {0x01, 0xf9}, {0xf3, 0xf2},
+ {0xf4, 0x02}, {0xe8, 0x03}, {0xec, 0xf0}, {0x04, 0xe1}, {0xe9, 0x05},
+ {0x06, 0x80}, {0xa0, 0x07}, {0x08, 0x09}, {0x0a, 0xe5}, {0xef, 0x0b},
+ {0x0c, 0x0d}, },
+ { {0x9b, 0xf5}, },
+ { {0x18, 0x19}, {0xba, 0xac}, {0xf6, 0x9b}, {0xf0, 0xe2}, {0x01, 0xe6},
+ {0x02, 0xa7}, {0xae, 0xe7}, {0x03, 0xe3}, {0xf5, 0x04}, {0xed, 0x05},
+ {0x06, 0x07}, {0xeb, 0x08}, {0x09, 0xee}, {0xf2, 0x0a}, {0xe4, 0x0b},
+ {0xf9, 0xec}, {0x0c, 0x0d}, {0xf4, 0x80}, {0x0e, 0xef}, {0xf3, 0xa0},
+ {0xe1, 0x0f}, {0xe9, 0x10}, {0x11, 0xe5}, {0x12, 0x13}, {0x14, 0x15},
+ {0x16, 0x17}, },
+ { {0x19, 0x1a}, {0xa7, 0xac}, {0xbf, 0xc3}, {0xc8, 0xe4}, {0xe6, 0xed},
+ {0xf2, 0xae}, {0xec, 0xee}, {0xf9, 0x01}, {0x02, 0x03}, {0x04, 0xba},
+ {0x05, 0x9b}, {0xf5, 0x06}, {0x07, 0x08}, {0x09, 0xeb}, {0xf0, 0x0a},
+ {0x0b, 0x0c}, {0xe1, 0xe3}, {0x0d, 0xe8}, {0x0e, 0x0f}, {0xef, 0x10},
+ {0x11, 0xf3}, {0x12, 0xe9}, {0x13, 0xe5}, {0x14, 0x15}, {0xf4, 0x16},
+ {0x17, 0xa0}, {0x18, 0x80}, },
+ { {0x14, 0x15}, {0xba, 0xbf}, {0xe4, 0xf7}, {0x9b, 0xa7}, {0x01, 0xee},
+ {0x02, 0x03}, {0x04, 0xe3}, {0xe2, 0xed}, {0x05, 0xf9}, {0x06, 0xf4},
+ {0x07, 0xec}, {0x08, 0xf5}, {0xf2, 0x09}, {0xe1, 0xf3}, {0x0a, 0xef},
+ {0x0b, 0x0c}, {0x0d, 0xe9}, {0x80, 0xe5}, {0x0e, 0xa0}, {0x0f, 0xe8},
+ {0x10, 0x11}, {0x12, 0x13}, },
+ { {0x11, 0x12}, {0xeb, 0xfa}, {0x80, 0xe6}, {0x9b, 0x01}, {0xa0, 0x02},
+ {0x03, 0xe9}, {0xe1, 0x04}, {0xe4, 0xf0}, {0xed, 0xe2}, {0xe3, 0xe7},
+ {0xec, 0x05}, {0xe5, 0x06}, {0x07, 0x08}, {0x09, 0xf4}, {0x0a, 0x0b},
+ {0x0c, 0xf3}, {0xee, 0x0d}, {0x0e, 0xf2}, {0x0f, 0x10}, },
+ { {0x04, 0xe5}, {0xf3, 0xef}, {0x9b, 0x01}, {0xe1, 0x02}, {0x03, 0xe9}, },
+ { {0x0b, 0x0c}, {0xa7, 0xe2}, {0xec, 0xe3}, {0xf2, 0x01}, {0x9b, 0x02},
+ {0x03, 0x04}, {0xe9, 0xef}, {0xee, 0xe5}, {0xe1, 0x80}, {0x05, 0xa0},
+ {0x06, 0x07}, {0x08, 0x09}, {0xf3, 0x0a}, },
+ { {0x05, 0x06}, {0x9b, 0xa0}, {0xe1, 0xe5}, {0xe9, 0x01}, {0x80, 0xf0},
+ {0x02, 0xf4}, {0x03, 0x04}, },
+ { {0xa0, 0x13}, {0xe3, 0xad}, {0xe4, 0xe9}, {0xee, 0xef}, {0xf0, 0xf4},
+ {0xf6, 0xa1}, {0xe1, 0xed}, {0x01, 0xe2}, {0x02, 0x03}, {0x04, 0xa7},
+ {0x05, 0x06}, {0xf7, 0x07}, {0x9b, 0xec}, {0x08, 0xe5}, {0x09, 0x0a},
+ {0x0b, 0x0c}, {0x0d, 0x0e}, {0xf3, 0x0f}, {0x10, 0x11}, {0x80, 0x12}, },
+ { {0x05, 0x06}, {0xe5, 0xfa}, {0xa0, 0xf9}, {0x9b, 0x01}, {0x80, 0xe9},
+ {0x02, 0xe1}, {0x03, 0x04}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+ { {0x9b, 0x9b}, },
+};
+
+
+
+static inline void huffbuff_init(struct huffbuff *hbuf, uint8_t *buf, uint32_t buf_len)
+{
+ memset(hbuf, 0, sizeof(struct huffbuff));
+ hbuf->buf = buf;
+ hbuf->buf_len = buf_len;
+}
+
+static inline int huffbuff_bits(struct huffbuff *hbuf, uint8_t nbits)
+{
+ uint8_t result = 0;
+
+ if (nbits > 8)
+ return -1;
+
+ while(nbits--) {
+ if (hbuf->cur_byte >= hbuf->buf_len) {
+ return -1;
+ }
+
+ result <<= 1;
+ if (hbuf->buf[hbuf->cur_byte] & (0x80 >> hbuf->cur_bit))
+ result |= 1;
+
+ if (++hbuf->cur_bit > 7) {
+ hbuf->cur_byte++;
+ hbuf->cur_bit = 0;
+ }
+ }
+
+ return result;
+}
+
+static inline int append_unicode_char(uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos,
+ uint32_t c)
+{
+ uint8_t tmp[3];
+ int tmplen = 0;
+
+ // encode the unicode character first of all
+ if (c < 0x80) {
+ tmp[0] = c;
+ tmplen = 1;
+ } else if (c < 0x800) {
+ tmp[0] = 0xc0 | ((c >> 6) & 0x1f);
+ tmp[1] = 0x80 | (c & 0x3f);
+ tmplen = 2;
+ } else if (c < 0x10000) {
+ tmp[0] = 0xe0 | ((c >> 12) & 0x0f);
+ tmp[1] = 0x80 | ((c >> 6) & 0x3f);
+ tmp[2] = 0x80 | (c & 0x3f);
+ tmplen = 3;
+ } else {
+ return -1;
+ }
+
+ // do we have enough buffer space?
+ if ((*destbufpos + tmplen) >= *destbuflen) {
+ uint8_t *new_dest = realloc(*destbuf, *destbuflen + DEST_ALLOC_DELTA);
+ if (new_dest == NULL)
+ return -ENOMEM;
+ *destbuf = new_dest;
+ *destbuflen += DEST_ALLOC_DELTA;
+ }
+
+ // copy it into position
+ memcpy(*destbuf + *destbufpos, tmp, tmplen);
+ *destbufpos += tmplen;
+
+ return 0;
+}
+
+static inline int unicode_decode(uint8_t *srcbuf, size_t srcbuflen, int mode,
+ uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos)
+{
+ size_t i;
+ uint32_t msb = mode << 8;
+
+ for(i=0; i< srcbuflen; i++) {
+ if (append_unicode_char(destbuf, destbuflen, destbufpos, msb + srcbuf[i]))
+ return -1;
+ }
+
+ return *destbufpos;
+}
+
+static int huffman_decode_uncompressed(struct huffbuff *hbuf,
+ uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos)
+{
+ int c;
+
+ while(hbuf->cur_byte < hbuf->buf_len) {
+ // get next byte
+ if ((c = huffbuff_bits(hbuf, 8)) < 0)
+ return -1;
+
+ switch(c) {
+ case HUFFSTRING_END:
+ return 0;
+
+ case HUFFSTRING_ESCAPE:
+ return HUFFSTRING_ESCAPE;
+
+ default:
+ if (append_unicode_char(destbuf, destbuflen, destbufpos, c))
+ return -1;
+
+ // if it is 7 bit, we swap back to the compressed context
+ if ((c & 0x80) == 0)
+ return c;
+
+ // characters following an 8 bit uncompressed char are uncompressed as well
+ break;
+ }
+ }
+
+ // ran out of string; pretend we saw an end of string char
+ return HUFFSTRING_END;
+}
+
+static int huffman_decode(uint8_t *src, size_t srclen,
+ uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos,
+ struct hufftree_entry hufftree[][128])
+{
+ struct huffbuff hbuf;
+ int bit;
+ struct hufftree_entry *tree = hufftree[0];
+ uint8_t treeidx = 0;
+ uint8_t treeval;
+ int tmp;
+
+ huffbuff_init(&hbuf, src, srclen);
+
+ while(hbuf.cur_byte < hbuf.buf_len) {
+ // get the next bit
+ if ((bit = huffbuff_bits(&hbuf, 1)) < 0)
+ return *destbufpos;
+
+ if (!bit) {
+ treeval = tree[treeidx].left_idx;
+ } else {
+ treeval = tree[treeidx].right_idx;
+ }
+
+ if (treeval & HUFFTREE_LITERAL_MASK) {
+ switch(treeval & ~HUFFTREE_LITERAL_MASK) {
+ case HUFFSTRING_END:
+ return 0;
+
+ case HUFFSTRING_ESCAPE:
+ if ((tmp =
+ huffman_decode_uncompressed(&hbuf,
+ destbuf, destbuflen, destbufpos)) < 0)
+ return tmp;
+ if (tmp == 0)
+ return *destbufpos;
+
+ tree = hufftree[tmp];
+ treeidx = 0;
+ break;
+
+ default:
+ // stash it
+ if (append_unicode_char(destbuf, destbuflen, destbufpos,
+ treeval & ~HUFFTREE_LITERAL_MASK))
+ return -1;
+ tree = hufftree[treeval & ~HUFFTREE_LITERAL_MASK];
+ treeidx = 0;
+ break;
+ }
+ } else {
+ treeidx = treeval;
+ }
+ }
+
+ return *destbufpos;
+}
+
+int atsc_text_segment_decode(struct atsc_text_string_segment *segment,
+ uint8_t **destbuf, size_t *destbufsize, size_t *destbufpos)
+{
+ if (segment->mode > ATSC_TEXT_SEGMENT_MODE_UNICODE_RANGE_MAX)
+ return -1;
+
+ // mode==0 MUST be used for compressed text
+ if ((segment->mode) && (segment->compression_type))
+ return -1;
+
+ uint8_t *buf = atsc_text_string_segment_bytes(segment);
+
+ switch(segment->compression_type) {
+ case ATSC_TEXT_COMPRESS_NONE:
+ return unicode_decode(buf, segment->number_bytes, segment->mode,
+ destbuf, destbufsize, destbufpos);
+
+ case ATSC_TEXT_COMPRESS_PROGRAM_TITLE:
+ return huffman_decode(buf, segment->number_bytes,
+ destbuf, destbufsize, destbufpos,
+ program_title_hufftree);
+
+ case ATSC_TEXT_COMPRESS_PROGRAM_DESCRIPTION:
+ return huffman_decode(buf, segment->number_bytes,
+ destbuf, destbufsize, destbufpos,
+ program_description_hufftree);
+ }
+
+ return -1;
+}
diff --git a/lib/libucsi/atsc/caption_service_descriptor.h b/lib/libucsi/atsc/caption_service_descriptor.h
new file mode 100644
index 0000000..29d1794
--- /dev/null
+++ b/lib/libucsi/atsc/caption_service_descriptor.h
@@ -0,0 +1,137 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_CAPTION_SERVICE_DESCRIPTOR
+#define _UCSI_ATSC_CAPTION_SERVICE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * atsc_caption_service_descriptor structure.
+ */
+struct atsc_caption_service_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 3; ,
+ uint8_t number_of_services : 5; );
+ /* struct atsc_caption_service_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a atsc_caption_service_descriptor.
+ */
+struct atsc_caption_service_entry {
+ iso639lang_t language_code;
+ EBIT3(uint8_t digital_cc : 1; ,
+ uint8_t reserved : 1; ,
+ uint8_t value : 6; );
+ EBIT3(uint16_t easy_reader : 1; ,
+ uint16_t wide_aspect_ratio : 1; ,
+ uint16_t reserved1 :14; );
+} __ucsi_packed;
+
+/**
+ * Process an atsc_caption_service_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_caption_service_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_caption_service_descriptor*
+ atsc_caption_service_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_caption_service_descriptor *ret =
+ (struct atsc_caption_service_descriptor *) d;
+ uint8_t *buf = (uint8_t*) d + 2;
+ int pos = 0;
+ int idx;
+
+ if (d->len < 1)
+ return NULL;
+ pos++;
+
+ for(idx = 0; idx < ret->number_of_services; idx++) {
+ if (d->len < (pos + sizeof(struct atsc_caption_service_entry)))
+ return NULL;
+
+ bswap16(buf+pos+4);
+
+ pos += sizeof(struct atsc_caption_service_entry);
+ }
+
+ return (struct atsc_caption_service_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field of a atsc_caption_service_descriptor.
+ *
+ * @param d atsc_caption_service_descriptor pointer.
+ * @param pos Variable holding a pointer to the current atsc_caption_service_entry.
+ * @param idx Field iterator integer.
+ */
+#define atsc_caption_service_descriptor_entries_for_each(d, pos, idx) \
+ for ((pos) = atsc_caption_service_descriptor_entries_first(d), idx=0; \
+ (pos); \
+ (pos) = atsc_caption_service_descriptor_entries_next(d, pos, ++idx))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_caption_service_entry*
+ atsc_caption_service_descriptor_entries_first(struct atsc_caption_service_descriptor *d)
+{
+ if (d->number_of_services == 0)
+ return NULL;
+
+ return (struct atsc_caption_service_entry *)
+ ((uint8_t*) d + sizeof(struct atsc_caption_service_descriptor));
+}
+
+static inline struct atsc_caption_service_entry*
+ atsc_caption_service_descriptor_entries_next(struct atsc_caption_service_descriptor *d,
+ struct atsc_caption_service_entry *pos,
+ int idx)
+{
+ if (idx >= d->number_of_services)
+ return NULL;
+
+ return (struct atsc_caption_service_entry *)
+ ((uint8_t *) pos + sizeof(struct atsc_caption_service_entry));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/component_name_descriptor.h b/lib/libucsi/atsc/component_name_descriptor.h
new file mode 100644
index 0000000..3b9cab7
--- /dev/null
+++ b/lib/libucsi/atsc/component_name_descriptor.h
@@ -0,0 +1,92 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_COMPONENT_NAME_DESCRIPTOR
+#define _UCSI_ATSC_COMPONENT_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+#include <libucsi/atsc/types.h>
+
+/**
+ * atsc_component_name_descriptor structure.
+ */
+struct atsc_component_name_descriptor {
+ struct descriptor d;
+
+ /* struct atsc_text text[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_component_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_component_name_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_component_name_descriptor*
+ atsc_component_name_descriptor_codec(struct descriptor* d)
+{
+ uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_component_name_descriptor);
+
+ if (atsc_text_validate(txt, d->len))
+ return NULL;
+
+ return (struct atsc_component_name_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of an atsc_component_name_descriptor.
+ *
+ * @param d atsc_component_name_descriptor pointer.
+ * @return Pointer to the atsc_text data, or NULL on error.
+ */
+static inline struct atsc_text*
+ atsc_component_name_descriptor_text(struct atsc_component_name_descriptor *d)
+{
+ uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_component_name_descriptor);
+
+ return (struct atsc_text*) txt;
+}
+
+/**
+ * Accessor for the length of the text field of an atsc_component_name_descriptor_text.
+ *
+ * @param d atsc_component_name_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ atsc_component_name_descriptor_text_length(struct atsc_component_name_descriptor *d)
+{
+ return d->d.len;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/content_advisory_descriptor.h b/lib/libucsi/atsc/content_advisory_descriptor.h
new file mode 100644
index 0000000..da19813
--- /dev/null
+++ b/lib/libucsi/atsc/content_advisory_descriptor.h
@@ -0,0 +1,235 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_CONTENT_ADVISORY_DESCRIPTOR
+#define _UCSI_ATSC_CONTENT_ADVISORY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * atsc_content_advisory_descriptor structure.
+ */
+struct atsc_content_advisory_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 2; ,
+ uint8_t rating_region_count : 6; );
+ /* struct atsc_content_advisory_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a atsc_content_advisory_descriptor.
+ */
+struct atsc_content_advisory_entry {
+ uint8_t rating_region;
+ uint8_t rated_dimensions;
+ /* struct atsc_content_advisory_entry_dimension dimensions[] */
+ /* struct atsc_content_advisory_entry_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a atsc_content_advisory_descriptor.
+ */
+struct atsc_content_advisory_entry_dimension {
+ uint8_t rating_dimension_j;
+ EBIT2(uint8_t reserved : 4; ,
+ uint8_t rating_value : 4; );
+} __ucsi_packed;
+
+/**
+ * Part2 of an atsc_content_advisory_entry.
+ */
+struct atsc_content_advisory_entry_part2 {
+ uint8_t rating_description_length;
+ /* struct atsc_text description */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_content_advisory_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_content_advisory_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_content_advisory_descriptor*
+ atsc_content_advisory_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_content_advisory_descriptor *ret =
+ (struct atsc_content_advisory_descriptor *) d;
+ uint8_t *buf = (uint8_t*) d + 2;
+ int pos = 0;
+ int idx;
+
+ if (d->len < 1)
+ return NULL;
+ pos++;
+
+ for(idx = 0; idx < ret->rating_region_count; idx++) {
+ if (d->len < (pos + sizeof(struct atsc_content_advisory_entry)))
+ return NULL;
+ struct atsc_content_advisory_entry *entry =
+ (struct atsc_content_advisory_entry *) (buf + pos);
+ pos += sizeof(struct atsc_content_advisory_entry);
+
+ if (d->len < (pos + (sizeof(struct atsc_content_advisory_entry_dimension) *
+ entry->rated_dimensions)))
+ return NULL;
+ pos += sizeof(struct atsc_content_advisory_entry_dimension) * entry->rated_dimensions;
+
+ if (d->len < (pos + sizeof(struct atsc_content_advisory_entry_part2)))
+ return NULL;
+ struct atsc_content_advisory_entry_part2 *part2 =
+ (struct atsc_content_advisory_entry_part2 *) (buf + pos);
+ pos += sizeof(struct atsc_content_advisory_entry_part2);
+
+ if (d->len < (pos + part2->rating_description_length))
+ return NULL;
+
+ if (atsc_text_validate(buf+pos, part2->rating_description_length))
+ return NULL;
+
+ pos += part2->rating_description_length;
+ }
+
+ return (struct atsc_content_advisory_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field of a atsc_content_advisory_descriptor.
+ *
+ * @param d atsc_content_advisory_descriptor pointer.
+ * @param pos Variable holding a pointer to the current atsc_content_advisory_entry.
+ * @param idx Integer used to count which entry we are in.
+ */
+#define atsc_content_advisory_descriptor_entries_for_each(d, pos, idx) \
+ for ((pos) = atsc_content_advisory_descriptor_entries_first(d), idx=0; \
+ (pos); \
+ (pos) = atsc_content_advisory_descriptor_entries_next(d, pos, ++idx))
+
+/**
+ * Iterator for dimensions field of a atsc_content_advisory_entry.
+ *
+ * @param d atsc_content_advisory_entry pointer.
+ * @param pos Variable holding a pointer to the current atsc_content_advisory_entry_dimension.
+ * @param idx Integer used to count which dimension we are in.
+ */
+#define atsc_content_advisory_entry_dimensions_for_each(d, pos, idx) \
+ for ((pos) = atsc_content_advisory_entry_dimensions_first(d), idx=0; \
+ (pos); \
+ (pos) = atsc_content_advisory_entry_dimensions_next(d, pos, ++idx))
+
+/**
+ * Accessor for the part2 field of an atsc_content_advisory_entry.
+ *
+ * @param entry atsc_content_advisory_entry pointer.
+ * @return struct atsc_content_advisory_entry_part2 pointer.
+ */
+static inline struct atsc_content_advisory_entry_part2 *
+ atsc_content_advisory_entry_part2(struct atsc_content_advisory_entry *entry)
+{
+ int pos = sizeof(struct atsc_content_advisory_entry);
+ pos += entry->rated_dimensions * sizeof(struct atsc_content_advisory_entry_dimension);
+
+ return (struct atsc_content_advisory_entry_part2 *) (((uint8_t*) entry) + pos);
+}
+
+
+/**
+ * Accessor for the description field of an atsc_content_advisory_entry_part2.
+ *
+ * @param part2 atsc_content_advisory_entry_part2 pointer.
+ * @return Pointer to the atsc_text data, or NULL on error.
+ */
+static inline struct atsc_text*
+ atsc_content_advisory_entry_part2_description(struct atsc_content_advisory_entry_part2 *part2)
+{
+ uint8_t *txt = ((uint8_t*) part2) + sizeof(struct atsc_content_advisory_entry_part2);
+
+ return (struct atsc_text *) txt;
+}
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_content_advisory_entry*
+ atsc_content_advisory_descriptor_entries_first(struct atsc_content_advisory_descriptor *d)
+{
+ if (d->rating_region_count == 0)
+ return NULL;
+
+ return (struct atsc_content_advisory_entry *)
+ ((uint8_t*) d + sizeof(struct atsc_content_advisory_descriptor));
+}
+
+static inline struct atsc_content_advisory_entry*
+ atsc_content_advisory_descriptor_entries_next(struct atsc_content_advisory_descriptor *d,
+ struct atsc_content_advisory_entry *pos,
+ int idx)
+{
+ if (idx >= d->rating_region_count)
+ return NULL;
+ struct atsc_content_advisory_entry_part2 *part2 =
+ atsc_content_advisory_entry_part2(pos);
+
+ return (struct atsc_content_advisory_entry *)
+ ((uint8_t *) part2 +
+ sizeof(struct atsc_content_advisory_entry_part2) +
+ part2->rating_description_length);
+}
+
+static inline struct atsc_content_advisory_entry_dimension*
+ atsc_content_advisory_entry_dimensions_first(struct atsc_content_advisory_entry *e)
+{
+ if (e->rated_dimensions == 0)
+ return NULL;
+
+ return (struct atsc_content_advisory_entry_dimension *)
+ ((uint8_t*) e + sizeof(struct atsc_content_advisory_entry));
+}
+
+static inline struct atsc_content_advisory_entry_dimension*
+ atsc_content_advisory_entry_dimensions_next(struct atsc_content_advisory_entry *e,
+ struct atsc_content_advisory_entry_dimension *pos,
+ int idx)
+{
+ uint8_t *next = (uint8_t *) pos + sizeof(struct atsc_content_advisory_entry_dimension);
+
+ if (idx >= e->rated_dimensions)
+ return NULL;
+ return (struct atsc_content_advisory_entry_dimension *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/cvct_section.c b/lib/libucsi/atsc/cvct_section.c
new file mode 100644
index 0000000..6edbc03
--- /dev/null
+++ b/lib/libucsi/atsc/cvct_section.c
@@ -0,0 +1,77 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/cvct_section.h>
+
+struct atsc_cvct_section *atsc_cvct_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = sizeof(struct atsc_section_psip);
+ size_t len = section_ext_length(&(psip->ext_head));
+ int idx;
+
+ if (len < sizeof(struct atsc_cvct_section))
+ return NULL;
+ struct atsc_cvct_section *cvct = (struct atsc_cvct_section *) psip;
+
+ pos++;
+ for(idx =0; idx < cvct->num_channels_in_section; idx++) {
+ if ((pos + sizeof(struct atsc_cvct_channel)) > len)
+ return NULL;
+ struct atsc_cvct_channel *channel = (struct atsc_cvct_channel *) (buf+pos);
+
+ pos += 7*2;
+
+ bswap32(buf+pos);
+ bswap32(buf+pos+4);
+ bswap16(buf+pos+8);
+ bswap16(buf+pos+10);
+ bswap16(buf+pos+12);
+ bswap16(buf+pos+14);
+ bswap16(buf+pos+16);
+ pos+=18;
+
+ if ((pos + channel->descriptors_length) > len)
+ return NULL;
+ if (verify_descriptors(buf + pos, channel->descriptors_length))
+ return NULL;
+
+ pos += channel->descriptors_length;
+ }
+
+ if ((pos + sizeof(struct atsc_cvct_section_part2)) > len)
+ return NULL;
+ struct atsc_cvct_section_part2 *part2 = (struct atsc_cvct_section_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+ pos+=2;
+
+ if ((pos + part2->descriptors_length) > len)
+ return NULL;
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+
+ pos += part2->descriptors_length;
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_cvct_section *) psip;
+}
diff --git a/lib/libucsi/atsc/cvct_section.h b/lib/libucsi/atsc/cvct_section.h
new file mode 100644
index 0000000..c3d418a
--- /dev/null
+++ b/lib/libucsi/atsc/cvct_section.h
@@ -0,0 +1,228 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_CVCT_SECTION_H
+#define _UCSI_ATSC_CVCT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+
+/**
+ * atsc_cvct_section structure.
+ */
+struct atsc_cvct_section {
+ struct atsc_section_psip head;
+
+ uint8_t num_channels_in_section;
+ /* struct atsc_cvct_channel channels[] */
+ /* struct atsc_cvct_channel_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_cvct_channel {
+ uint16_t short_name[7]; // UTF-16 network ordered
+ EBIT4(uint32_t reserved : 4; ,
+ uint32_t major_channel_number :10; ,
+ uint32_t minor_channel_number :10; ,
+ uint32_t modulation_mode : 8; );
+ uint32_t carrier_frequency;
+ uint16_t channel_TSID;
+ uint16_t program_number;
+ EBIT8(uint16_t ETM_location : 2; ,
+ uint16_t access_controlled : 1; ,
+ uint16_t hidden : 1; ,
+ uint16_t path_select : 1; ,
+ uint16_t out_of_band : 1; ,
+ uint16_t hide_guide : 1; ,
+ uint16_t reserved2 : 3; ,
+ uint16_t service_type : 6; );
+ uint16_t source_id;
+ EBIT2(uint16_t reserved3 : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct atsc_cvct_section_part2 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+static inline struct atsc_cvct_channel *atsc_cvct_section_channels_first(struct atsc_cvct_section *cvct);
+static inline struct atsc_cvct_channel *
+ atsc_cvct_section_channels_next(struct atsc_cvct_section *cvct, struct atsc_cvct_channel *pos, int idx);
+
+/**
+ * Process a atsc_cvct_section.
+ *
+ * @param section Pointer to anj atsc_section_psip structure.
+ * @return atsc_cvct_section pointer, or NULL on error.
+ */
+struct atsc_cvct_section *atsc_cvct_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the transport_stream_id field of a CVCT.
+ *
+ * @param cvdt CVDT pointer.
+ * @return The transport_stream_id.
+ */
+static inline uint16_t atsc_cvct_section_transport_stream_id(struct atsc_cvct_section *cvct)
+{
+ return cvct->head.ext_head.table_id_ext;
+}
+
+/**
+ * Iterator for the tables field in an atsc_cvct_section.
+ *
+ * @param mgt atsc_cvct_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_cvct_channel.
+ * @param idx Integer used to count which table we in.
+ */
+#define atsc_cvct_section_channels_for_each(mgt, pos, idx) \
+ for ((pos) = atsc_cvct_section_channels_first(mgt), idx=0; \
+ (pos); \
+ (pos) = atsc_cvct_section_channels_next(mgt, pos, ++idx))
+
+/**
+ * Iterator for the descriptors field in a atsc_cvct_channel structure.
+ *
+ * @param table atsc_cvct_channel pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_cvct_channel_descriptors_for_each(table, pos) \
+ for ((pos) = atsc_cvct_channel_descriptors_first(table); \
+ (pos); \
+ (pos) = atsc_cvct_channel_descriptors_next(table, pos))
+
+/**
+ * Accessor for the second part of an atsc_cvct_section.
+ *
+ * @param mgt atsc_cvct_section pointer.
+ * @return atsc_cvct_section_part2 pointer.
+ */
+static inline struct atsc_cvct_section_part2 *
+ atsc_cvct_section_part2(struct atsc_cvct_section *mgt)
+{
+ int pos = sizeof(struct atsc_cvct_section);
+
+ struct atsc_cvct_channel *cur_table;
+ int idx;
+ atsc_cvct_section_channels_for_each(mgt, cur_table, idx) {
+ pos += sizeof(struct atsc_cvct_channel);
+ pos += cur_table->descriptors_length;
+ }
+
+ return (struct atsc_cvct_section_part2 *) (((uint8_t*) mgt) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_cvct_section structure.
+ *
+ * @param part2 atsc_cvct_section_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_cvct_section_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_cvct_section_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_cvct_section_part2_descriptors_next(part2, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_cvct_channel *
+ atsc_cvct_section_channels_first(struct atsc_cvct_section *cvct)
+{
+ size_t pos = sizeof(struct atsc_cvct_section);
+
+ if (cvct->num_channels_in_section == 0)
+ return NULL;
+
+ return (struct atsc_cvct_channel*) (((uint8_t *) cvct) + pos);
+}
+
+static inline struct atsc_cvct_channel *
+ atsc_cvct_section_channels_next(struct atsc_cvct_section *cvct,
+ struct atsc_cvct_channel *pos,
+ int idx)
+{
+ if (idx >= cvct->num_channels_in_section)
+ return NULL;
+
+ return (struct atsc_cvct_channel *)
+ (((uint8_t*) pos) + sizeof(struct atsc_cvct_channel) + pos->descriptors_length);
+}
+
+static inline struct descriptor *
+ atsc_cvct_channel_descriptors_first(struct atsc_cvct_channel *table)
+{
+ size_t pos = sizeof(struct atsc_cvct_channel);
+
+ if (table->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) table) + pos);
+}
+
+static inline struct descriptor *
+ atsc_cvct_channel_descriptors_next(struct atsc_cvct_channel *table,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) table + sizeof(struct atsc_cvct_channel),
+ table->descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ atsc_cvct_section_part2_descriptors_first(struct atsc_cvct_section_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_cvct_section_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_cvct_section_part2_descriptors_next(struct atsc_cvct_section_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_cvct_section_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/dcc_arriving_request_descriptor.h b/lib/libucsi/atsc/dcc_arriving_request_descriptor.h
new file mode 100644
index 0000000..af76eac
--- /dev/null
+++ b/lib/libucsi/atsc/dcc_arriving_request_descriptor.h
@@ -0,0 +1,107 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_DCC_ARRIVING_REQUEST_DESCRIPTOR
+#define _UCSI_ATSC_DCC_ARRIVING_REQUEST_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+enum atsc_dcc_arriving_request_type {
+ DCC_ARRIVAL_TYPE_DEFER_10SEC = 0x01,
+ DCC_ARRIVAL_TYPE_DEFER = 0x02,
+};
+
+/**
+ * atsc_dcc_arriving_request_descriptor structure.
+ */
+struct atsc_dcc_arriving_request_descriptor {
+ struct descriptor d;
+
+ uint8_t dcc_arriving_request_type;
+ uint8_t dcc_arriving_request_text_length;
+ /* struct atsc_text text[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_dcc_arriving_request_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_dcc_arriving_request_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_dcc_arriving_request_descriptor*
+ atsc_dcc_arriving_request_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_dcc_arriving_request_descriptor *ret =
+ (struct atsc_dcc_arriving_request_descriptor *) d;
+
+ if (d->len < 2)
+ return NULL;
+
+ if (d->len != 2 + ret->dcc_arriving_request_text_length)
+ return NULL;
+
+ if (atsc_text_validate((uint8_t*) d + sizeof(struct atsc_dcc_arriving_request_descriptor),
+ ret->dcc_arriving_request_text_length))
+ return NULL;
+
+ return (struct atsc_dcc_arriving_request_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of an atsc_dcc_arriving_request_descriptor.
+ *
+ * @param d atsc_dcc_arriving_request_descriptor pointer.
+ * @return Pointer to the atsc_text data, or NULL on error.
+ */
+static inline struct atsc_text*
+ atsc_dcc_arriving_request_descriptor_text(struct atsc_dcc_arriving_request_descriptor *d)
+{
+ uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_dcc_arriving_request_descriptor);
+
+ return (struct atsc_text*) txt;
+}
+
+/**
+ * Accessor for the length of the text field of an atsc_dcc_arriving_request_descriptor.
+ *
+ * @param d atsc_dcc_arriving_request_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ atsc_dcc_arriving_request_descriptor_text_length(struct
+ atsc_dcc_arriving_request_descriptor *d)
+{
+ return d->d.len - 2;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/dcc_departing_request_descriptor.h b/lib/libucsi/atsc/dcc_departing_request_descriptor.h
new file mode 100644
index 0000000..851f0cc
--- /dev/null
+++ b/lib/libucsi/atsc/dcc_departing_request_descriptor.h
@@ -0,0 +1,108 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_DCC_DEPARTING_REQUEST_DESCRIPTOR
+#define _UCSI_ATSC_DCC_DEPARTING_REQUEST_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+enum atsc_dcc_departing_request_type {
+ DCC_DEPART_TYPE_IMMEDIATE = 0x01,
+ DCC_DEPART_TYPE_DEFER_10SEC = 0x02,
+ DCC_DEPART_TYPE_DEFER = 0x03,
+};
+
+/**
+ * atsc_dcc_departing_request_descriptor structure.
+ */
+struct atsc_dcc_departing_request_descriptor {
+ struct descriptor d;
+
+ uint8_t dcc_departing_request_type;
+ uint8_t dcc_departing_request_text_length;
+ /* struct atsc_text text[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_dcc_departing_request_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_dcc_departing_request_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_dcc_departing_request_descriptor*
+ atsc_dcc_departing_request_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_dcc_departing_request_descriptor *ret =
+ (struct atsc_dcc_departing_request_descriptor *) d;
+
+ if (d->len < 2)
+ return NULL;
+
+ if (d->len != 2 + ret->dcc_departing_request_text_length)
+ return NULL;
+
+ if (atsc_text_validate(((uint8_t*) d) + sizeof(struct atsc_dcc_departing_request_descriptor),
+ ret->dcc_departing_request_text_length))
+ return NULL;
+
+ return (struct atsc_dcc_departing_request_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of an atsc_dcc_departing_request_descriptor.
+ *
+ * @param d atsc_dcc_departing_request_descriptor pointer.
+ * @return Pointer to the atsc_text data, or NULL on error.
+ */
+static inline struct atsc_text*
+ atsc_dcc_departing_request_descriptor_text(struct atsc_dcc_departing_request_descriptor *d)
+{
+ uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_dcc_departing_request_descriptor);
+
+ return (struct atsc_text*) txt;
+}
+
+/**
+ * Accessor for the length of the text field of an atsc_dcc_departing_request_descriptor.
+ *
+ * @param d atsc_dcc_departing_request_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ atsc_dcc_departing_request_descriptor_text_length(struct
+ atsc_dcc_departing_request_descriptor *d)
+{
+ return d->d.len - 2;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/dccsct_section.c b/lib/libucsi/atsc/dccsct_section.c
new file mode 100644
index 0000000..59ad069
--- /dev/null
+++ b/lib/libucsi/atsc/dccsct_section.c
@@ -0,0 +1,109 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/dccsct_section.h>
+
+struct atsc_dccsct_section *atsc_dccsct_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = 0;
+ size_t len = section_ext_length(&(psip->ext_head));
+ int idx;
+
+ if (len < sizeof(struct atsc_dccsct_section))
+ return NULL;
+ struct atsc_dccsct_section *dccsct = (struct atsc_dccsct_section *) psip;
+
+ pos += sizeof(struct atsc_dccsct_section);
+ for(idx =0; idx < dccsct->updates_defined; idx++) {
+ if (len < (pos + sizeof(struct atsc_dccsct_update)))
+ return NULL;
+ struct atsc_dccsct_update *update = (struct atsc_dccsct_update *) (buf+pos);
+
+ pos += sizeof(struct atsc_dccsct_update);
+ if (len < (pos + update->update_data_length))
+ return NULL;
+
+ switch(update->update_type) {
+ case ATSC_DCCST_UPDATE_NEW_GENRE: {
+ int sublen = sizeof(struct atsc_dccsct_update_new_genre);
+ if (update->update_data_length < sublen)
+ return NULL;
+
+ if (atsc_text_validate(buf+pos+sublen, update->update_data_length - sublen))
+ return NULL;
+ break;
+ }
+ case ATSC_DCCST_UPDATE_NEW_STATE: {
+ int sublen = sizeof(struct atsc_dccsct_update_new_state);
+ if (update->update_data_length < sublen)
+ return NULL;
+
+ if (atsc_text_validate(buf+pos+sublen, update->update_data_length - sublen))
+ return NULL;
+ break;
+ }
+ case ATSC_DCCST_UPDATE_NEW_COUNTY: {
+ int sublen = sizeof(struct atsc_dccsct_update_new_county);
+ if (update->update_data_length < sublen)
+ return NULL;
+ bswap16(buf+pos+1);
+
+ if (atsc_text_validate(buf+pos+sublen, update->update_data_length - sublen))
+ return NULL;
+ break;
+ }
+ }
+
+ pos += update->update_data_length;
+ if (len < (pos + sizeof(struct atsc_dccsct_update_part2)))
+ return NULL;
+ struct atsc_dccsct_update_part2 *part2 = (struct atsc_dccsct_update_part2 *) buf + pos;
+
+ bswap16(buf+pos);
+
+ pos += sizeof(struct atsc_dccsct_update_part2);
+ if (len < (pos + part2->descriptors_length))
+ return NULL;
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+
+ pos += part2->descriptors_length;
+ }
+
+ if (len < (pos + sizeof(struct atsc_dccsct_section_part2)))
+ return NULL;
+ struct atsc_dccsct_section_part2 *part2 = (struct atsc_dccsct_section_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+
+ pos += sizeof(struct atsc_dccsct_section_part2);
+ if (len < (pos + part2->descriptors_length))
+ return NULL;
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+
+ pos += part2->descriptors_length;
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_dccsct_section *) psip;
+}
diff --git a/lib/libucsi/atsc/dccsct_section.h b/lib/libucsi/atsc/dccsct_section.h
new file mode 100644
index 0000000..f9f3522
--- /dev/null
+++ b/lib/libucsi/atsc/dccsct_section.h
@@ -0,0 +1,327 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_DCCSCT_SECTION_H
+#define _UCSI_ATSC_DCCSCT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+#include <libucsi/atsc/types.h>
+
+enum atsc_dccst_update_types {
+ ATSC_DCCST_UPDATE_NEW_GENRE = 0x01,
+ ATSC_DCCST_UPDATE_NEW_STATE = 0x02,
+ ATSC_DCCST_UPDATE_NEW_COUNTY = 0x03,
+};
+
+/**
+ * atsc_dccsct_section structure.
+ */
+struct atsc_dccsct_section {
+ struct atsc_section_psip head;
+
+ uint8_t updates_defined;
+ /* struct atsc_dccsct_update updates */
+ /* struct atsc_dccsct_section_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_dccsct_update {
+ uint8_t update_type;
+ uint8_t update_data_length;
+ /* struct atsc_dccsct_update_XXX data -- depends on update_type */
+ /* struct atsc_dccsct_update_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_dccsct_update_new_genre {
+ uint8_t genre_category_code;
+ /* atsc_text name */
+} __ucsi_packed;
+
+struct atsc_dccsct_update_new_state {
+ uint8_t dcc_state_location_code;
+ /* atsc_text name */
+} __ucsi_packed;
+
+struct atsc_dccsct_update_new_county {
+ uint8_t state_code;
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t dcc_county_location_code :10; );
+ /* atsc_text name */
+} __ucsi_packed;
+
+struct atsc_dccsct_update_part2 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct atsc_dccsct_section_part2 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_dccsct_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_dccsct_section pointer, or NULL on error.
+ */
+struct atsc_dccsct_section *atsc_dccsct_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the dccsct_type field of a dccsct.
+ *
+ * @param dccsct dccsct pointer.
+ * @return The dccsct_type.
+ */
+static inline uint16_t atsc_dccsct_section_dccsct_type(struct atsc_dccsct_section *dccsct)
+{
+ return dccsct->head.ext_head.table_id_ext;
+}
+
+/**
+ * Iterator for the updates field in an atsc_dccsct_section.
+ *
+ * @param dccsct atsc_dccsct_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_dccsct_update.
+ * @param idx Integer used to count which test we are in.
+ */
+#define atsc_dccsct_section_updates_for_each(dccsct, pos, idx) \
+ for ((pos) = atsc_dccsct_section_updates_first(dccsct), idx=0; \
+ (pos); \
+ (pos) = atsc_dccsct_section_updates_next(dccsct, pos, ++idx))
+
+/**
+ * Accessor for the data field of a new genre atsc_dccsct_update.
+ *
+ * @param update atsc_dccsct_update pointer.
+ * @return struct atsc_dccsct_update_new_genre pointer.
+ */
+static inline struct atsc_dccsct_update_new_genre *atsc_dccsct_update_new_genre(struct atsc_dccsct_update *update)
+{
+ if (update->update_type != ATSC_DCCST_UPDATE_NEW_GENRE)
+ return NULL;
+
+ return (struct atsc_dccsct_update_new_genre *)
+ (((uint8_t*) update) + sizeof(struct atsc_dccsct_update));
+}
+
+/**
+ * Accessor for the name field of an atsc_dccsct_update_new_genre.
+ *
+ * @param update atsc_dccsct_update_new_genre pointer.
+ * @return text pointer.
+ */
+static inline struct atsc_text *atsc_dccsct_update_new_genre_name(struct atsc_dccsct_update *update)
+{
+ if ((update->update_data_length - 1) == 0)
+ return NULL;
+
+ return (struct atsc_text *)
+ (((uint8_t*) update) + sizeof(struct atsc_dccsct_update_new_genre));
+}
+
+/**
+ * Accessor for the data field of a new state atsc_dccsct_update.
+ *
+ * @param update atsc_dccsct_update pointer.
+ * @return struct atsc_dccsct_update_new_state pointer.
+ */
+static inline struct atsc_dccsct_update_new_state *
+ atsc_dccsct_update_new_state(struct atsc_dccsct_update *update)
+{
+ if (update->update_type != ATSC_DCCST_UPDATE_NEW_STATE)
+ return NULL;
+
+ return (struct atsc_dccsct_update_new_state *)
+ (((uint8_t*) update) + sizeof(struct atsc_dccsct_update));
+}
+
+/**
+ * Accessor for the name field of an atsc_dccsct_update_new_state.
+ *
+ * @param update atsc_dccsct_update_new_state pointer.
+ * @return text pointer.
+ */
+static inline struct atsc_text *atsc_dccsct_update_new_state_name(struct atsc_dccsct_update *update)
+{
+ if ((update->update_data_length - 1) == 0)
+ return NULL;
+
+ return (struct atsc_text *)
+ (((uint8_t*) update) + sizeof(struct atsc_dccsct_update_new_state));
+}
+
+/**
+ * Accessor for the data field of a new county atsc_dccsct_update.
+ *
+ * @param update atsc_dccsct_update pointer.
+ * @return struct atsc_dccsct_update_new_county pointer.
+ */
+static inline struct atsc_dccsct_update_new_county *
+ atsc_dccsct_update_new_county(struct atsc_dccsct_update *update)
+{
+ if (update->update_type != ATSC_DCCST_UPDATE_NEW_COUNTY)
+ return NULL;
+
+ return (struct atsc_dccsct_update_new_county *)
+ (((uint8_t*) update) + sizeof(struct atsc_dccsct_update));
+}
+
+/**
+ * Accessor for the name field of an atsc_dccsct_update_new_county.
+ *
+ * @param update atsc_dccsct_update_new_county pointer.
+ * @return text pointer.
+ */
+static inline struct atsc_text *atsc_dccsct_update_new_county_name(struct atsc_dccsct_update *update)
+{
+ if ((update->update_data_length - 3) == 0)
+ return NULL;
+
+ return (struct atsc_text*)
+ (((uint8_t*) update) + sizeof(struct atsc_dccsct_update_new_county));
+}
+
+/**
+ * Accessor for the part2 field of an atsc_dccsct_update.
+ *
+ * @param update atsc_dccsct_update pointer.
+ * @return struct atsc_dccsct_test_part2 pointer.
+ */
+static inline struct atsc_dccsct_update_part2 *atsc_dccsct_update_part2(struct atsc_dccsct_update *update)
+{
+ int pos = sizeof(struct atsc_dccsct_update);
+ pos += update->update_data_length;
+
+ return (struct atsc_dccsct_update_part2 *) (((uint8_t*) update) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in an atsc_dccsct_update_part2 structure.
+ *
+ * @param part2 atsc_dccsct_update_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_dccsct_update_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_dccsct_update_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_dccsct_update_part2_descriptors_next(part2, pos))
+
+/**
+ * Iterator for the descriptors field in a atsc_dccsct_section_part2 structure.
+ *
+ * @param part2 atsc_dccsct_section_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_dccsct_section_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_dccsct_section_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_dccsct_section_part2_descriptors_next(part2, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_dccsct_update *
+ atsc_dccsct_section_updates_first(struct atsc_dccsct_section *dccsct)
+{
+ size_t pos = sizeof(struct atsc_dccsct_section);
+
+ if (dccsct->updates_defined == 0)
+ return NULL;
+
+ return (struct atsc_dccsct_update*) (((uint8_t *) dccsct) + pos);
+}
+
+static inline struct atsc_dccsct_update*
+ atsc_dccsct_section_updates_next(struct atsc_dccsct_section *dccsct,
+ struct atsc_dccsct_update *pos,
+ int idx)
+{
+ if (idx >= dccsct->updates_defined)
+ return NULL;
+
+ struct atsc_dccsct_update_part2 *part2 = atsc_dccsct_update_part2(pos);
+ int len = sizeof(struct atsc_dccsct_update_part2);
+ len += part2->descriptors_length;
+
+ return (struct atsc_dccsct_update *) (((uint8_t*) part2) + len);
+}
+
+static inline struct descriptor *
+ atsc_dccsct_update_part2_descriptors_first(struct atsc_dccsct_update_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_dccsct_update_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_dccsct_update_part2_descriptors_next(struct atsc_dccsct_update_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dccsct_update_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ atsc_dccsct_section_part2_descriptors_first(struct atsc_dccsct_section_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_dccsct_section_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_dccsct_section_part2_descriptors_next(struct atsc_dccsct_section_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dccsct_section_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/dcct_section.c b/lib/libucsi/atsc/dcct_section.c
new file mode 100644
index 0000000..7d0b83b
--- /dev/null
+++ b/lib/libucsi/atsc/dcct_section.c
@@ -0,0 +1,96 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/dcct_section.h>
+
+struct atsc_dcct_section *atsc_dcct_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = 0;
+ size_t len = section_ext_length(&(psip->ext_head));
+ int testidx;
+ int termidx;
+
+ if (len < sizeof(struct atsc_dcct_section))
+ return NULL;
+ struct atsc_dcct_section *dcct = (struct atsc_dcct_section *) psip;
+
+ pos += sizeof(struct atsc_dcct_section);
+ for(testidx =0; testidx < dcct->dcc_test_count; testidx++) {
+ if (len < (pos + sizeof(struct atsc_dcct_test)))
+ return NULL;
+ struct atsc_dcct_test *test = (struct atsc_dcct_test *) (buf+pos);
+
+ bswap24(buf+pos);
+ bswap24(buf+pos+3);
+ bswap32(buf+pos+6);
+ bswap32(buf+pos+10);
+
+ pos += sizeof(struct atsc_dcct_test);
+ for(termidx =0; termidx < test->dcc_term_count; termidx++) {
+ if (len < (pos + sizeof(struct atsc_dcct_term)))
+ return NULL;
+ struct atsc_dcct_term *term = (struct atsc_dcct_term *) (buf+pos);
+
+ bswap64(buf+pos+1);
+ bswap16(buf+pos+9);
+
+ pos += sizeof(struct atsc_dcct_term);
+ if (len < (pos + term->descriptors_length))
+ return NULL;
+ if (verify_descriptors(buf + pos, term->descriptors_length))
+ return NULL;
+
+ pos += term->descriptors_length;
+ }
+
+ if (len < (pos + sizeof(struct atsc_dcct_test_part2)))
+ return NULL;
+ struct atsc_dcct_test_part2 *part2 = (struct atsc_dcct_test_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+
+ pos += sizeof(struct atsc_dcct_test_part2);
+ if (len < (pos + part2->descriptors_length))
+ return NULL;
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+ pos += part2->descriptors_length;
+ }
+
+ if (len < (pos + sizeof(struct atsc_dcct_section_part2)))
+ return NULL;
+ struct atsc_dcct_section_part2 *part2 = (struct atsc_dcct_section_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+
+ pos += sizeof(struct atsc_dcct_section_part2);
+ if (len < (pos + part2->descriptors_length))
+ return NULL;
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+
+ pos += part2->descriptors_length;
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_dcct_section *) psip;
+}
diff --git a/lib/libucsi/atsc/dcct_section.h b/lib/libucsi/atsc/dcct_section.h
new file mode 100644
index 0000000..647bd4b
--- /dev/null
+++ b/lib/libucsi/atsc/dcct_section.h
@@ -0,0 +1,380 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_DCCT_SECTION_H
+#define _UCSI_ATSC_DCCT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+#include <libucsi/atsc/types.h>
+
+enum atsc_dcc_context {
+ ATSC_DCC_CONTEXT_TEMPORARY_RETUNE = 0,
+ ATSC_DCC_CONTEXT_CHANNEL_REDIRECT = 1,
+};
+
+enum atsc_dcc_selection_type {
+ ATSC_DCC_SELECTION_UNCONDITIONAL_CHANNEL_CHANGE = 0x00,
+ ATSC_DCC_SELECTION_NUMERIC_POSTAL_CODE_INCLUSION = 0x01,
+ ATSC_DCC_SELECTION_ALPHANUMERIC_POSTAL_CODE_INCLUSION = 0x02,
+ ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_ONE_OR_MORE = 0x05,
+ ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_ALL = 0x06,
+ ATSC_DCC_SELECTION_GENRE_CATEGORY_ONE_OR_MORE = 0x07,
+ ATSC_DCC_SELECTION_GENRE_CATEGORY_ALL = 0x08,
+ ATSC_DCC_SELECTION_CANNOT_BE_AUTHORIZED = 0x09,
+ ATSC_DCC_SELECTION_GEOGRAPHIC_LOCATION_INCLUSION = 0x0c,
+ ATSC_DCC_SELECTION_RATING_BLOCKED = 0x0d,
+ ATSC_DCC_SELECTION_RETURN_TO_ORIGINAL_CHANNEL = 0x0f,
+ ATSC_DCC_SELECTION_NUMERIC_POSTAL_CODE_EXCLUSION = 0x11,
+ ATSC_DCC_SELECTION_ALPHANUMERIC_POSTAL_CODE_EXCLUSION = 0x12,
+ ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_NOT_ONE_OR_MORE = 0x15,
+ ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_NOT_ALL = 0x16,
+ ATSC_DCC_SELECTION_GENRE_CATEGORY_NOT_ONE_OR_MORE = 0x17,
+ ATSC_DCC_SELECTION_GENRE_CATEGORY_NOT_ALL = 0x18,
+ ATSC_DCC_SELECTION_GEOGRAPHIC_LOCATION_EXCLUSION = 0x1c,
+ ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_A = 0x20,
+ ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_B = 0x21,
+ ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_C = 0x22,
+ ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_D = 0x23,
+};
+
+/**
+ * atsc_dcct_section structure.
+ */
+struct atsc_dcct_section {
+ struct atsc_section_psip head;
+
+ uint8_t dcc_test_count;
+ /* struct atsc_dcct_test tests */
+ /* struct atsc_dcct_section_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_dcct_test {
+ EBIT4(uint32_t dcc_context : 1; ,
+ uint32_t reserved : 3; ,
+ uint32_t dcc_from_major_channel_number :10; ,
+ uint32_t dcc_from_minor_channel_number :10; );
+ EBIT3(uint32_t reserved1 : 4; ,
+ uint32_t dcc_to_major_channel_number :10; ,
+ uint32_t dcc_to_minor_channel_number :10; );
+ atsctime_t start_time;
+ atsctime_t end_time;
+ uint8_t dcc_term_count;
+ /* struct atsc_dcct_term terms */
+ /* struct atsc_dcct_test_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_dcct_term {
+ uint8_t dcc_selection_type;
+ uint64_t dcc_selection_id;
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct atsc_dcct_test_part2 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct atsc_dcct_section_part2 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+static inline struct atsc_dcct_test *
+ atsc_dcct_section_tests_first(struct atsc_dcct_section *dcct);
+static inline struct atsc_dcct_test *
+ atsc_dcct_section_tests_next(struct atsc_dcct_section *dcct,
+ struct atsc_dcct_test *pos,
+ int idx);
+static inline struct atsc_dcct_term *
+ atsc_dcct_test_terms_first(struct atsc_dcct_test *test);
+static inline struct atsc_dcct_term *
+ atsc_dcct_test_terms_next(struct atsc_dcct_test *test,
+ struct atsc_dcct_term *pos,
+ int idx);
+
+
+/**
+ * Process an atsc_dcct_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_dcct_section pointer, or NULL on error.
+ */
+struct atsc_dcct_section *atsc_dcct_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the dcc_subtype field of a dcct.
+ *
+ * @param dcct dcct pointer.
+ * @return The dcc_subtype.
+ */
+static inline uint8_t atsc_dcct_section_dcc_subtype(struct atsc_dcct_section *dcct)
+{
+ return dcct->head.ext_head.table_id_ext >> 8;
+}
+
+/**
+ * Accessor for the dcc_id field of a dcct.
+ *
+ * @param dcct dcct pointer.
+ * @return The dcc_id.
+ */
+static inline uint8_t atsc_dcct_section_dcc_id(struct atsc_dcct_section *dcct)
+{
+ return dcct->head.ext_head.table_id_ext & 0xff;
+}
+
+/**
+ * Iterator for the tests field in an atsc_dcct_section.
+ *
+ * @param dcct atsc_dcct_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_dcct_test.
+ * @param idx Integer used to count which test we are in.
+ */
+#define atsc_dcct_section_tests_for_each(dcct, pos, idx) \
+ for ((pos) = atsc_dcct_section_tests_first(dcct), idx=0; \
+ (pos); \
+ (pos) = atsc_dcct_section_tests_next(dcct, pos, ++idx))
+
+/**
+ * Iterator for the terms field in an atsc_dcct_test.
+ *
+ * @param test atsc_dcct_test pointer.
+ * @param pos Variable containing a pointer to the current atsc_dcct_term.
+ * @param idx Integer used to count which test we are in.
+ */
+#define atsc_dcct_test_terms_for_each(test, pos, idx) \
+ for ((pos) = atsc_dcct_test_terms_first(test), idx=0; \
+ (pos); \
+ (pos) = atsc_dcct_test_terms_next(test, pos, ++idx))
+
+/**
+ * Iterator for the descriptors field in a atsc_dcct_term structure.
+ *
+ * @param term atsc_dcct_term pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_dcct_term_descriptors_for_each(term, pos) \
+ for ((pos) = atsc_dcct_term_descriptors_first(term); \
+ (pos); \
+ (pos) = atsc_dcct_term_descriptors_next(term, pos))
+
+/**
+ * Accessor for the part2 field of an atsc_dcct_test.
+ *
+ * @param test atsc_dcct_test pointer.
+ * @return struct atsc_dcct_test_part2 pointer.
+ */
+static inline struct atsc_dcct_test_part2 *atsc_dcct_test_part2(struct atsc_dcct_test *test)
+{
+ int pos = sizeof(struct atsc_dcct_test);
+
+ struct atsc_dcct_term *cur_term;
+ int idx;
+ atsc_dcct_test_terms_for_each(test, cur_term, idx) {
+ pos += sizeof(struct atsc_dcct_term);
+ pos += cur_term->descriptors_length;
+ }
+
+ return (struct atsc_dcct_test_part2 *) (((uint8_t*) test) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_dcct_test_part2 structure.
+ *
+ * @param term atsc_dcct_test_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_dcct_test_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_dcct_test_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_dcct_test_part2_descriptors_next(part2, pos))
+
+/**
+ * Accessor for the part2 field of an atsc_dcct_section.
+ *
+ * @param dcct atsc_dcct_section pointer.
+ * @return struct atsc_dcct_section_part2 pointer.
+ */
+static inline struct atsc_dcct_section_part2 *atsc_dcct_section_part2(struct atsc_dcct_section *dcct)
+{
+ int pos = sizeof(struct atsc_dcct_section);
+
+ struct atsc_dcct_test *cur_test;
+ int testidx;
+ atsc_dcct_section_tests_for_each(dcct, cur_test, testidx) {
+ struct atsc_dcct_test_part2 *part2 = atsc_dcct_test_part2(cur_test);
+ pos += ((uint8_t*) part2 - (uint8_t*) cur_test);
+
+ pos += sizeof(struct atsc_dcct_test_part2);
+ pos += part2->descriptors_length;
+ }
+
+ return (struct atsc_dcct_section_part2 *) (((uint8_t*) dcct) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_dcct_section_part2 structure.
+ *
+ * @param part2 atsc_dcct_section_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_dcct_section_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_dcct_section_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_dcct_section_part2_descriptors_next(part2, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_dcct_test *
+ atsc_dcct_section_tests_first(struct atsc_dcct_section *dcct)
+{
+ size_t pos = sizeof(struct atsc_dcct_section);
+
+ if (dcct->dcc_test_count == 0)
+ return NULL;
+
+ return (struct atsc_dcct_test*) (((uint8_t *) dcct) + pos);
+}
+
+static inline struct atsc_dcct_test *
+ atsc_dcct_section_tests_next(struct atsc_dcct_section *dcct,
+ struct atsc_dcct_test *pos,
+ int idx)
+{
+ if (idx >= dcct->dcc_test_count)
+ return NULL;
+
+ struct atsc_dcct_test_part2 *part2 = atsc_dcct_test_part2(pos);
+ int len = sizeof(struct atsc_dcct_test_part2);
+ len += part2->descriptors_length;
+
+ return (struct atsc_dcct_test *) (((uint8_t*) part2) + len);
+}
+
+static inline struct atsc_dcct_term *
+ atsc_dcct_test_terms_first(struct atsc_dcct_test *test)
+{
+ size_t pos = sizeof(struct atsc_dcct_test);
+
+ if (test->dcc_term_count == 0)
+ return NULL;
+
+ return (struct atsc_dcct_term*) (((uint8_t *) test) + pos);
+}
+
+static inline struct atsc_dcct_term *
+ atsc_dcct_test_terms_next(struct atsc_dcct_test *test,
+ struct atsc_dcct_term *pos,
+ int idx)
+{
+ if (idx >= test->dcc_term_count)
+ return NULL;
+
+ int len = sizeof(struct atsc_dcct_term);
+ len += pos->descriptors_length;
+
+ return (struct atsc_dcct_term *) (((uint8_t*) pos) + len);
+}
+
+static inline struct descriptor *
+ atsc_dcct_term_descriptors_first(struct atsc_dcct_term *term)
+{
+ size_t pos = sizeof(struct atsc_dcct_term);
+
+ if (term->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) term) + pos);
+}
+
+static inline struct descriptor *
+ atsc_dcct_term_descriptors_next(struct atsc_dcct_term *term,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) term + sizeof(struct atsc_dcct_term),
+ term->descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ atsc_dcct_test_part2_descriptors_first(struct atsc_dcct_test_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_dcct_test_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_dcct_test_part2_descriptors_next(struct atsc_dcct_test_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dcct_test_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ atsc_dcct_section_part2_descriptors_first(struct atsc_dcct_section_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_dcct_section_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_dcct_section_part2_descriptors_next(struct atsc_dcct_section_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dcct_section_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/descriptor.h b/lib/libucsi/atsc/descriptor.h
new file mode 100644
index 0000000..a57176a
--- /dev/null
+++ b/lib/libucsi/atsc/descriptor.h
@@ -0,0 +1,68 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_DESCRIPTOR_H
+#define _UCSI_ATSC_DESCRIPTOR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/endianops.h>
+#include <libucsi/atsc/stuffing_descriptor.h>
+#include <libucsi/atsc/ac3_descriptor.h>
+#include <libucsi/atsc/caption_service_descriptor.h>
+#include <libucsi/atsc/component_name_descriptor.h>
+#include <libucsi/atsc/content_advisory_descriptor.h>
+#include <libucsi/atsc/dcc_arriving_request_descriptor.h>
+#include <libucsi/atsc/dcc_departing_request_descriptor.h>
+#include <libucsi/atsc/extended_channel_name_descriptor.h>
+#include <libucsi/atsc/genre_descriptor.h>
+#include <libucsi/atsc/rc_descriptor.h>
+#include <libucsi/atsc/service_location_descriptor.h>
+#include <libucsi/atsc/time_shifted_service_descriptor.h>
+
+/**
+ * Enumeration of ATSC descriptor tags.
+ */
+enum atsc_descriptor_tag {
+ dtag_atsc_stuffing = 0x80,
+ dtag_atsc_ac3_audio = 0x81,
+ dtag_atsc_caption_service = 0x86,
+ dtag_atsc_content_advisory = 0x87,
+ dtag_atsc_extended_channel_name = 0xa0,
+ dtag_atsc_service_location = 0xa1,
+ dtag_atsc_time_shifted_service = 0xa2,
+ dtag_atsc_component_name = 0xa3,
+ dtag_atsc_dcc_departing_request = 0xa8,
+ dtag_atsc_dcc_arriving_request = 0xa9,
+ dtag_atsc_redistribution_control = 0xaa,
+ dtag_atsc_private_information = 0xad,
+ dtag_atsc_content_identifier = 0xb6,
+ dtag_atsc_genre = 0xab,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/eit_section.c b/lib/libucsi/atsc/eit_section.c
new file mode 100644
index 0000000..48cdda6
--- /dev/null
+++ b/lib/libucsi/atsc/eit_section.c
@@ -0,0 +1,71 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/eit_section.h>
+
+struct atsc_eit_section *atsc_eit_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = 0;
+ size_t len = section_ext_length(&(psip->ext_head));
+ int idx;
+
+ if (len < sizeof(struct atsc_eit_section))
+ return NULL;
+ struct atsc_eit_section *eit = (struct atsc_eit_section *) psip;
+
+ pos += sizeof(struct atsc_eit_section);
+ for(idx =0; idx < eit->num_events_in_section; idx++) {
+ if (len < (pos + sizeof(struct atsc_eit_event)))
+ return NULL;
+ struct atsc_eit_event *event = (struct atsc_eit_event *) (buf+pos);
+
+ bswap16(buf+pos);
+ bswap32(buf+pos+2);
+ bswap32(buf+pos+6);
+
+ pos += sizeof(struct atsc_eit_event);
+ if (len < (pos + event->title_length))
+ return NULL;
+ if (atsc_text_validate(buf+pos, event->title_length))
+ return NULL;
+
+ pos += event->title_length;
+ if (len < (pos + sizeof(struct atsc_eit_event_part2)))
+ return NULL;
+ struct atsc_eit_event_part2 *part2 = (struct atsc_eit_event_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+
+ pos += sizeof(struct atsc_eit_event_part2);
+ if (len < (pos + part2->descriptors_length))
+ return NULL;
+
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+ pos += part2->descriptors_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_eit_section *) psip;
+}
diff --git a/lib/libucsi/atsc/eit_section.h b/lib/libucsi/atsc/eit_section.h
new file mode 100644
index 0000000..84bef16
--- /dev/null
+++ b/lib/libucsi/atsc/eit_section.h
@@ -0,0 +1,191 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_EIT_SECTION_H
+#define _UCSI_ATSC_EIT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+#include <libucsi/atsc/types.h>
+
+/**
+ * atsc_eit_section structure.
+ */
+struct atsc_eit_section {
+ struct atsc_section_psip head;
+
+ uint8_t num_events_in_section;
+ /* struct atsc_eit_event events[] */
+} __ucsi_packed;
+
+struct atsc_eit_event {
+ EBIT2(uint16_t reserved : 2; ,
+ uint16_t event_id :14; );
+ atsctime_t start_time;
+ EBIT4(uint32_t reserved1 : 2; ,
+ uint32_t ETM_location : 2; ,
+ uint32_t length_in_seconds :20; ,
+ uint32_t title_length : 8; );
+ /* struct atsc_text title_text */
+ /* struct atsc_eit_event_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_eit_event_part2 {
+ EBIT2(uint16_t reserved : 4; ,
+ uint16_t descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+
+/**
+ * Process a atsc_eit_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_eit_section pointer, or NULL on error.
+ */
+struct atsc_eit_section *atsc_eit_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the source_id field of an EIT.
+ *
+ * @param eit EIT pointer.
+ * @return The source_id .
+ */
+static inline uint16_t atsc_eit_section_source_id(struct atsc_eit_section *eit)
+{
+ return eit->head.ext_head.table_id_ext;
+}
+
+/**
+ * Iterator for the events field in an atsc_eit_section.
+ *
+ * @param eit atsc_eit_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_eit_event.
+ * @param idx Integer used to count which event we are in.
+ */
+#define atsc_eit_section_events_for_each(eit, pos, idx) \
+ for ((pos) = atsc_eit_section_events_first(eit), idx=0; \
+ (pos); \
+ (pos) = atsc_eit_section_events_next(eit, pos, ++idx))
+
+/**
+ * Accessor for the title_text field of an atsc_eit_event.
+ *
+ * @param event atsc_eit_event pointer.
+ * @return struct atsc_text pointer, or NULL on error.
+ */
+static inline struct atsc_text *atsc_eit_event_name_title_text(struct atsc_eit_event *event)
+{
+ if (event->title_length == 0)
+ return NULL;
+
+ return (struct atsc_text*)(((uint8_t*) event) + sizeof(struct atsc_eit_event));
+}
+
+/**
+ * Accessor for the part2 field of an atsc_eit_event.
+ *
+ * @param event atsc_eit_event pointer.
+ * @return struct atsc_eit_event_part2 pointer.
+ */
+static inline struct atsc_eit_event_part2 *atsc_eit_event_part2(struct atsc_eit_event *event)
+{
+ return (struct atsc_eit_event_part2 *)
+ (((uint8_t*) event) + sizeof(struct atsc_eit_event) + event->title_length);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_eit_section structure.
+ *
+ * @param part2 atsc_eit_event_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_eit_event_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_eit_event_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_eit_event_part2_descriptors_next(part2, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_eit_event *
+ atsc_eit_section_events_first(struct atsc_eit_section *eit)
+{
+ size_t pos = sizeof(struct atsc_eit_section);
+
+ if (eit->num_events_in_section == 0)
+ return NULL;
+
+ return (struct atsc_eit_event*) (((uint8_t *) eit) + pos);
+}
+
+static inline struct atsc_eit_event *
+ atsc_eit_section_events_next(struct atsc_eit_section *eit,
+ struct atsc_eit_event *pos,
+ int idx)
+{
+ if (idx >= eit->num_events_in_section)
+ return NULL;
+
+ struct atsc_eit_event_part2 *part2 = atsc_eit_event_part2(pos);
+ int len = sizeof(struct atsc_eit_event_part2);
+ len += part2->descriptors_length;
+
+ return (struct atsc_eit_event *) (((uint8_t*) part2) + len);
+}
+
+static inline struct descriptor *
+ atsc_eit_event_part2_descriptors_first(struct atsc_eit_event_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_eit_event_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_eit_event_part2_descriptors_next(struct atsc_eit_event_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_eit_event_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/ett_section.c b/lib/libucsi/atsc/ett_section.c
new file mode 100644
index 0000000..ab2ff9c
--- /dev/null
+++ b/lib/libucsi/atsc/ett_section.c
@@ -0,0 +1,42 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/ett_section.h>
+#include <libucsi/atsc/types.h>
+
+struct atsc_ett_section *atsc_ett_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = sizeof(struct atsc_section_psip);
+ size_t len = section_ext_length(&(psip->ext_head));
+
+ if (len < sizeof(struct atsc_ett_section))
+ return NULL;
+
+ bswap32(buf + pos);
+ pos += 4;
+
+ if (atsc_text_validate(buf + pos,
+ section_ext_length(&psip->ext_head) - sizeof(struct atsc_ett_section)))
+ return NULL;
+
+ return (struct atsc_ett_section *) psip;
+}
diff --git a/lib/libucsi/atsc/ett_section.h b/lib/libucsi/atsc/ett_section.h
new file mode 100644
index 0000000..e2bb510
--- /dev/null
+++ b/lib/libucsi/atsc/ett_section.h
@@ -0,0 +1,91 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_ETT_SECTION_H
+#define _UCSI_ATSC_ETT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+
+enum atsc_etm_type {
+ ATSC_ETM_CHANNEL = 0x00,
+ ATSC_ETM_EVENT = 0x02,
+};
+
+/**
+ * atsc_ett_section structure.
+ */
+struct atsc_ett_section {
+ struct atsc_section_psip head;
+
+ EBIT3(uint32_t ETM_source_id :16; ,
+ uint32_t ETM_sub_id :14; ,
+ uint32_t ETM_type : 2; );
+ /* struct atsc_text extended_text_message */
+} __ucsi_packed;
+
+/**
+ * Process a atsc_ett_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_ett_section pointer, or NULL on error.
+ */
+struct atsc_ett_section *atsc_ett_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the extended_text_message part of an atsc_ett_section.
+ *
+ * @param ett atsc_ett_section pointer.
+ * @return atsc_text pointer, or NULL on error.
+ */
+static inline struct atsc_text*
+ atsc_ett_section_extended_text_message(struct atsc_ett_section *ett)
+{
+ int pos = sizeof(struct atsc_ett_section);
+ int len = section_ext_length(&ett->head.ext_head) - sizeof(struct atsc_ett_section);
+
+ if (len == 0)
+ return NULL;
+
+ return (struct atsc_text*)(((uint8_t*) ett) + pos);
+}
+
+/**
+ * Accessor for the extended_text_message part of an atsc_ett_section.
+ *
+ * @param ett atsc_ett_section pointer.
+ * @return The length.
+ */
+static inline int
+ atsc_ett_section_extended_text_message_length(struct atsc_ett_section *ett)
+{
+ return section_ext_length(&ett->head.ext_head) - sizeof(struct atsc_ett_section);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/extended_channel_name_descriptor.h b/lib/libucsi/atsc/extended_channel_name_descriptor.h
new file mode 100644
index 0000000..d0b714b
--- /dev/null
+++ b/lib/libucsi/atsc/extended_channel_name_descriptor.h
@@ -0,0 +1,92 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR
+#define _UCSI_ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+#include <libucsi/atsc/types.h>
+
+/**
+ * atsc_extended_channel_name_descriptor structure.
+ */
+struct atsc_extended_channel_name_descriptor {
+ struct descriptor d;
+
+ /* struct atsc_text text[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_extended_channel_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_extended_channel_name_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_extended_channel_name_descriptor*
+ atsc_extended_channel_name_descriptor_codec(struct descriptor* d)
+{
+ if (atsc_text_validate(((uint8_t*) d) + sizeof(struct atsc_extended_channel_name_descriptor),
+ d->len))
+ return NULL;
+
+ return (struct atsc_extended_channel_name_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of an atsc_extended_channel_name_descriptor.
+ *
+ * @param d atsc_extended_channel_name_descriptor pointer.
+ * @return Pointer to the atsc_text data, or NULL on error.
+ */
+static inline struct atsc_text*
+ atsc_extended_channel_name_descriptor_text(struct atsc_extended_channel_name_descriptor *d)
+{
+ uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_extended_channel_name_descriptor);
+
+ return (struct atsc_text*) txt;
+}
+
+/**
+ * Accessor for the length of the text field of an atsc_extended_channel_name_descriptor.
+ *
+ * @param d atsc_extended_channel_name_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ atsc_extended_channel_name_descriptor_text_length(struct
+ atsc_extended_channel_name_descriptor *d)
+{
+ return d->d.len;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/genre_descriptor.h b/lib/libucsi/atsc/genre_descriptor.h
new file mode 100644
index 0000000..a6fc542
--- /dev/null
+++ b/lib/libucsi/atsc/genre_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_GENRE_DESCRIPTOR
+#define _UCSI_ATSC_GENRE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * atsc_genre_descriptor structure.
+ */
+struct atsc_genre_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 3; ,
+ uint8_t attribute_count : 5; );
+ /* uint8_t attributes[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_genre_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_genre_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_genre_descriptor*
+ atsc_genre_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_genre_descriptor *ret =
+ (struct atsc_genre_descriptor *) d;
+
+ if (d->len < 1)
+ return NULL;
+
+ if (d->len != (1 + ret->attribute_count))
+ return NULL;
+
+ return (struct atsc_genre_descriptor*) d;
+}
+
+/**
+ * Accessor for the attributes field of an atsc_genre_descriptor.
+ *
+ * @param d atsc_genre_descriptor pointer.
+ * @return Pointer to the attributes.
+ */
+static inline uint8_t*
+ atsc_genre_descriptor_attributes(struct atsc_genre_descriptor *d)
+{
+ return ((uint8_t*) d) + sizeof(struct atsc_genre_descriptor);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/mgt_section.c b/lib/libucsi/atsc/mgt_section.c
new file mode 100644
index 0000000..bc6b3f2
--- /dev/null
+++ b/lib/libucsi/atsc/mgt_section.c
@@ -0,0 +1,76 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/mgt_section.h>
+
+struct atsc_mgt_section *atsc_mgt_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = sizeof(struct atsc_section_psip);
+ size_t len = section_ext_length(&(psip->ext_head));
+ struct atsc_mgt_section *mgt = (struct atsc_mgt_section *) psip;
+ int i;
+
+ if (len < sizeof(struct atsc_mgt_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+
+ // we cannot use the tables_defined value here because of the braindead ATSC spec!
+ for(i=0; i < mgt->tables_defined; i++) {
+ // we think we're still in the tables - process as normal
+ if ((pos + sizeof(struct atsc_mgt_table)) > len)
+ return NULL;
+ struct atsc_mgt_table *table = (struct atsc_mgt_table *) (buf+pos);
+
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap32(buf+pos+5);
+ bswap16(buf+pos+9);
+
+ pos += sizeof(struct atsc_mgt_table);
+ if ((pos + table->table_type_descriptors_length) > len)
+ return NULL;
+ if (verify_descriptors(buf + pos, table->table_type_descriptors_length))
+ return NULL;
+
+ pos += table->table_type_descriptors_length;
+ }
+
+ if ((pos + sizeof(struct atsc_mgt_section_part2)) > len)
+ return NULL;
+ struct atsc_mgt_section_part2 *part2 = (struct atsc_mgt_section_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+
+ pos += sizeof(struct atsc_mgt_section_part2);
+ if ((pos + part2->descriptors_length) > len)
+ return NULL;
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+ pos += part2->descriptors_length;
+
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_mgt_section *) psip;
+}
diff --git a/lib/libucsi/atsc/mgt_section.h b/lib/libucsi/atsc/mgt_section.h
new file mode 100644
index 0000000..3102a54
--- /dev/null
+++ b/lib/libucsi/atsc/mgt_section.h
@@ -0,0 +1,215 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_MGT_SECTION_H
+#define _UCSI_ATSC_MGT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+
+enum atsc_mgt_section_table_type {
+ ATSC_MGT_TABLE_TYPE_TVCT_CURRENT = 0,
+ ATSC_MGT_TABLE_TYPE_TVCT_NEXT = 1,
+ ATSC_MGT_TABLE_TYPE_CVCT_CURRENT = 2,
+ ATSC_MGT_TABLE_TYPE_CVCT_NEXT = 3,
+ ATSC_MGT_TABLE_TYPE_CHANNEL_ETT = 4,
+ ATSC_MGT_TABLE_TYPE_DCCSCT = 5,
+};
+
+/**
+ * atsc_mgt_section structure.
+ */
+struct atsc_mgt_section {
+ struct atsc_section_psip head;
+
+ uint16_t tables_defined;
+ /* struct atsc_mgt_table tables[] */
+ /* struct atsc_mgt_section_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_mgt_table {
+ uint16_t table_type;
+ EBIT2(uint16_t reserved : 3; ,
+ uint16_t table_type_PID :13; );
+ EBIT2(uint8_t reserved1 : 3; ,
+ uint8_t table_type_version_number : 5; );
+ uint32_t number_bytes;
+ EBIT2(uint16_t reserved2 : 4; ,
+ uint16_t table_type_descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct atsc_mgt_section_part2 {
+ EBIT2(uint16_t reserved : 4; ,
+ uint16_t descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+static inline struct atsc_mgt_table * atsc_mgt_section_tables_first(struct atsc_mgt_section *mgt);
+static inline struct atsc_mgt_table *
+ atsc_mgt_section_tables_next(struct atsc_mgt_section *mgt, struct atsc_mgt_table *pos, int idx);
+
+/**
+ * Process a atsc_mgt_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_mgt_section pointer, or NULL on error.
+ */
+struct atsc_mgt_section *atsc_mgt_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Iterator for the tables field in an atsc_mgt_section.
+ *
+ * @param mgt atsc_mgt_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_mgt_table.
+ * @param idx Integer used to count which table we in.
+ */
+#define atsc_mgt_section_tables_for_each(mgt, pos, idx) \
+ for ((pos) = atsc_mgt_section_tables_first(mgt), idx=0; \
+ (pos); \
+ (pos) = atsc_mgt_section_tables_next(mgt, pos, ++idx))
+
+/**
+ * Iterator for the descriptors field in a atsc_mgt_table structure.
+ *
+ * @param table atsc_mgt_table pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_mgt_table_descriptors_for_each(table, pos) \
+ for ((pos) = atsc_mgt_table_descriptors_first(table); \
+ (pos); \
+ (pos) = atsc_mgt_table_descriptors_next(table, pos))
+
+/**
+ * Accessor for the second part of an atsc_mgt_section.
+ *
+ * @param mgt atsc_mgt_section pointer.
+ * @return atsc_mgt_section_part2 pointer.
+ */
+static inline struct atsc_mgt_section_part2 *
+ atsc_mgt_section_part2(struct atsc_mgt_section *mgt)
+{
+ int pos = sizeof(struct atsc_mgt_section);
+
+ struct atsc_mgt_table *cur_table;
+ int idx;
+ atsc_mgt_section_tables_for_each(mgt, cur_table, idx) {
+ pos += sizeof(struct atsc_mgt_table);
+ pos += cur_table->table_type_descriptors_length;
+ }
+
+ return (struct atsc_mgt_section_part2 *) (((uint8_t*) mgt) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_mgt_section structure.
+ *
+ * @param part2 atsc_mgt_section_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_mgt_section_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_mgt_section_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_mgt_section_part2_descriptors_next(part2, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_mgt_table *
+ atsc_mgt_section_tables_first(struct atsc_mgt_section *mgt)
+{
+ size_t pos = sizeof(struct atsc_mgt_section);
+
+ if (mgt->tables_defined == 0)
+ return NULL;
+
+ return (struct atsc_mgt_table*) (((uint8_t *) mgt) + pos);
+}
+
+static inline struct atsc_mgt_table *
+ atsc_mgt_section_tables_next(struct atsc_mgt_section *mgt,
+ struct atsc_mgt_table *pos,
+ int idx)
+{
+ if (idx >= mgt->tables_defined)
+ return NULL;
+
+ return (struct atsc_mgt_table *)
+ (((uint8_t*) pos) + sizeof(struct atsc_mgt_table) + pos->table_type_descriptors_length);
+}
+
+static inline struct descriptor *
+ atsc_mgt_table_descriptors_first(struct atsc_mgt_table *table)
+{
+ size_t pos = sizeof(struct atsc_mgt_table);
+
+ if (table->table_type_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) table) + pos);
+}
+
+static inline struct descriptor *
+ atsc_mgt_table_descriptors_next(struct atsc_mgt_table *table,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) table + sizeof(struct atsc_mgt_table),
+ table->table_type_descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ atsc_mgt_section_part2_descriptors_first(struct atsc_mgt_section_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_mgt_section_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_mgt_section_part2_descriptors_next(struct atsc_mgt_section_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_mgt_section_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/rc_descriptor.h b/lib/libucsi/atsc/rc_descriptor.h
new file mode 100644
index 0000000..4fb0e8e
--- /dev/null
+++ b/lib/libucsi/atsc/rc_descriptor.h
@@ -0,0 +1,83 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_RC_DESCRIPTOR
+#define _UCSI_ATSC_RC_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * atsc_rc_descriptor structure.
+ */
+struct atsc_rc_descriptor {
+ struct descriptor d;
+
+ /* uint8_t info[] */
+} __ucsi_packed;
+
+/**
+ * Process an atsc_rc_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_rc_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_rc_descriptor*
+ atsc_rc_descriptor_codec(struct descriptor* d)
+{
+ return (struct atsc_rc_descriptor*) d;
+}
+
+/**
+ * Accessor for the info field of an atsc_rc_descriptor.
+ *
+ * @param d atsc_rc_descriptor pointer.
+ * @return Pointer to the atsc_text data.
+ */
+static inline uint8_t*
+ atsc_rc_descriptor_info(struct atsc_rc_descriptor *d)
+{
+ return ((uint8_t*) d) + sizeof(struct atsc_rc_descriptor);
+}
+
+/**
+ * Accessor for the length of the info field of an atsc_rc_descriptor.
+ *
+ * @param d atsc_rc_descriptor pointer.
+ * @return The length
+ */
+static inline int
+ atsc_rc_descriptor_info_length(struct atsc_rc_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/rrt_section.c b/lib/libucsi/atsc/rrt_section.c
new file mode 100644
index 0000000..6e96c3a
--- /dev/null
+++ b/lib/libucsi/atsc/rrt_section.c
@@ -0,0 +1,108 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/rrt_section.h>
+
+struct atsc_rrt_section *atsc_rrt_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = 0;
+ size_t len = section_ext_length(&(psip->ext_head));
+ int idx;
+ int vidx;
+ struct atsc_rrt_section *rrt = (struct atsc_rrt_section *) psip;
+
+ if (len < sizeof(struct atsc_rrt_section))
+ return NULL;
+ pos += sizeof(struct atsc_rrt_section);
+
+ if (len < (pos + rrt->rating_region_name_length))
+ return NULL;
+ if (atsc_text_validate(buf+pos, rrt->rating_region_name_length))
+ return NULL;
+
+ pos += rrt->rating_region_name_length;
+ if (len < (pos + sizeof(struct atsc_rrt_section_part2)))
+ return NULL;
+ struct atsc_rrt_section_part2 *rrtpart2 = (struct atsc_rrt_section_part2 *) (buf+pos);
+
+ pos += sizeof(struct atsc_rrt_section_part2);
+ for(idx =0; idx < rrtpart2->dimensions_defined; idx++) {
+ if (len < (pos + sizeof(struct atsc_rrt_dimension)))
+ return NULL;
+ struct atsc_rrt_dimension *dimension = (struct atsc_rrt_dimension *) (buf+pos);
+
+ pos += sizeof(struct atsc_rrt_dimension);
+ if (len < (pos + dimension->dimension_name_length))
+ return NULL;
+ if (atsc_text_validate(buf+pos, dimension->dimension_name_length))
+ return NULL;
+
+ pos += dimension->dimension_name_length;
+ if (len < (pos + sizeof(struct atsc_rrt_dimension_part2)))
+ return NULL;
+ struct atsc_rrt_dimension_part2 *dpart2 = (struct atsc_rrt_dimension_part2 *) (buf+pos);
+
+ pos += sizeof(struct atsc_rrt_dimension_part2);
+ for(vidx =0; vidx < dpart2->values_defined; vidx++) {
+ if (len < (pos + sizeof(struct atsc_rrt_dimension_value)))
+ return NULL;
+ struct atsc_rrt_dimension_value *value = (struct atsc_rrt_dimension_value *) (buf+pos);
+
+ pos += sizeof(struct atsc_rrt_dimension_value);
+ if (len < (pos + value->abbrev_rating_value_length))
+ return NULL;
+ if (atsc_text_validate(buf+pos, value->abbrev_rating_value_length))
+ return NULL;
+
+ pos += value->abbrev_rating_value_length;
+ if (len < (pos + sizeof(struct atsc_rrt_dimension_value_part2)))
+ return NULL;
+ struct atsc_rrt_dimension_value_part2 *vpart2 =
+ (struct atsc_rrt_dimension_value_part2 *) (buf+pos);
+
+ pos += sizeof(struct atsc_rrt_dimension_value_part2);
+ if (len < (pos + vpart2->rating_value_length))
+ return NULL;
+ if (atsc_text_validate(buf+pos, vpart2->rating_value_length))
+ return NULL;
+
+ pos+= vpart2->rating_value_length;
+ }
+ }
+
+ if (len < (pos + sizeof(struct atsc_rrt_section_part3)))
+ return NULL;
+ struct atsc_rrt_section_part3 *part3 = (struct atsc_rrt_section_part3 *) (buf+pos);
+
+ pos += sizeof(struct atsc_rrt_section_part3);
+ if (len < (pos + part3->descriptors_length))
+ return NULL;
+
+ if (verify_descriptors(buf + pos, part3->descriptors_length))
+ return NULL;
+
+ pos += part3->descriptors_length;
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_rrt_section *) psip;
+}
diff --git a/lib/libucsi/atsc/rrt_section.h b/lib/libucsi/atsc/rrt_section.h
new file mode 100644
index 0000000..fba4596
--- /dev/null
+++ b/lib/libucsi/atsc/rrt_section.h
@@ -0,0 +1,379 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_RRT_SECTION_H
+#define _UCSI_ATSC_RRT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+#include <libucsi/atsc/types.h>
+
+/**
+ * atsc_rrt_section structure.
+ */
+struct atsc_rrt_section {
+ struct atsc_section_psip head;
+
+ uint8_t rating_region_name_length;
+ /* struct atsc_text rating_region_name_text */
+ /* struct atsc_rrt_section_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_rrt_section_part2 {
+ uint8_t dimensions_defined;
+ /* struct atsc_rrt_dimension dimensions[] */
+ /* struct atsc_rrt_section_part3 part3 */
+} __ucsi_packed;
+
+struct atsc_rrt_dimension {
+ uint8_t dimension_name_length;
+ /* struct atsc_text dimension_name_text */
+ /* struct atsc_rrt_dimension_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_rrt_dimension_part2 {
+ EBIT3(uint8_t reserved : 3; ,
+ uint8_t graduated_scale : 1; ,
+ uint8_t values_defined : 4; );
+ /* struct atsc_rrt_dimension_value values[] */
+} __ucsi_packed;
+
+struct atsc_rrt_dimension_value {
+ uint8_t abbrev_rating_value_length;
+ /* struct atsc_text abbrev_rating_value_text */
+ /* struct atsc_rrt_dimension_value_part2 */
+} __ucsi_packed;
+
+struct atsc_rrt_dimension_value_part2 {
+ uint8_t rating_value_length;
+ /* struct atsc_text rating_value_text */
+} __ucsi_packed;
+
+struct atsc_rrt_section_part3 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+
+static inline struct atsc_rrt_dimension *
+ atsc_rrt_section_dimensions_first(struct atsc_rrt_section_part2 *part2);
+static inline struct atsc_rrt_dimension *
+ atsc_rrt_section_dimensions_next(struct atsc_rrt_section_part2 *part2,
+ struct atsc_rrt_dimension *pos,
+ int idx);
+static inline struct atsc_rrt_dimension_value *
+ atsc_rrt_dimension_part2_values_first(struct atsc_rrt_dimension_part2 *part2);
+static inline struct atsc_rrt_dimension_value *
+ atsc_rrt_dimension_part2_values_next(struct atsc_rrt_dimension_part2 *part2,
+ struct atsc_rrt_dimension_value *pos,
+ int idx);
+
+/**
+ * Process a atsc_rrt_section.
+ *
+ * @param section Pointer to anj atsc_section_psip structure.
+ * @return atsc_rrt_section pointer, or NULL on error.
+ */
+struct atsc_rrt_section *atsc_rrt_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the rating_region field of an RRT.
+ *
+ * @param rrt RRT pointer.
+ * @return The transport_stream_id.
+ */
+static inline uint8_t atsc_rrt_section_rating_region(struct atsc_rrt_section *rrt)
+{
+ return rrt->head.ext_head.table_id_ext & 0xff;
+}
+
+/**
+ * Accessor for the rating_region_name_text field of an RRT.
+ *
+ * @param rrt RRT pointer.
+ * @return struct atsc_text pointer, or NULL.
+ */
+static inline struct atsc_text *atsc_rrt_section_rating_region_name_text(struct atsc_rrt_section *rrt)
+{
+ if (rrt->rating_region_name_length == 0)
+ return NULL;
+
+ return (struct atsc_text*)(((uint8_t*) rrt) + sizeof(struct atsc_rrt_section));
+}
+
+/**
+ * Accessor for the part2 field of an RRT.
+ *
+ * @param rrt RRT pointer.
+ * @return struct atsc_rrt_section_part2 pointer.
+ */
+static inline struct atsc_rrt_section_part2 *atsc_rrt_section_part2(struct atsc_rrt_section *rrt)
+{
+ return (struct atsc_rrt_section_part2 *)
+ (((uint8_t*) rrt) + sizeof(struct atsc_rrt_section) +
+ rrt->rating_region_name_length);
+}
+
+/**
+ * Iterator for the dimensions field in an atsc_rrt_section_part2.
+ *
+ * @param rrt atsc_rrt_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_rrt_dimension.
+ * @param idx Integer used to count which dimension we are in.
+ */
+#define atsc_rrt_section_dimensions_for_each(rrt, pos, idx) \
+ for ((pos) = atsc_rrt_section_dimensions_first(rrt), idx=0; \
+ (pos); \
+ (pos) = atsc_rrt_section_dimensions_next(rrt, pos, ++idx))
+
+/**
+ * Accessor for the dimension_name_text field of an atsc_rrt_dimension.
+ *
+ * @param dimension atsc_rrt_dimension pointer.
+ * @return struct atsc_text pointer, or NULL on error.
+ */
+static inline struct atsc_text *atsc_rrt_dimension_name_text(struct atsc_rrt_dimension *dimension)
+{
+ if (dimension->dimension_name_length == 0)
+ return NULL;
+
+ return (struct atsc_text*)(((uint8_t*) dimension) + sizeof(struct atsc_rrt_dimension));
+}
+
+/**
+ * Accessor for the part2 field of an atsc_rrt_dimension.
+ *
+ * @param dimension atsc_rrt_dimension pointer.
+ * @return struct atsc_rrt_dimension_part2 pointer.
+ */
+static inline struct atsc_rrt_dimension_part2 *atsc_rrt_dimension_part2(struct atsc_rrt_dimension *dimension)
+{
+ return (struct atsc_rrt_dimension_part2 *)
+ (((uint8_t*) dimension) +
+ sizeof(struct atsc_rrt_dimension) +
+ dimension->dimension_name_length);
+}
+
+/**
+ * Iterator for the values field in a atsc_rrt_dimension_part2 structure.
+ *
+ * @param part2 atsc_rrt_dimension_part2 pointer.
+ * @param pos Variable containing a pointer to the current value.
+ * @param idx Integer used to count which value we are in
+ */
+#define atsc_rrt_dimension_part2_values_for_each(part2, pos, idx) \
+ for ((pos) = atsc_rrt_dimension_part2_values_first(part2), idx=0; \
+ (pos); \
+ (pos) = atsc_rrt_dimension_part2_values_next(part2, pos, ++idx))
+
+/**
+ * Accessor for the dimension_name_text field of an atsc_rrt_dimension.
+ *
+ * @param dimension atsc_rrt_dimension pointer.
+ * @return struct atsc_text pointer.
+ */
+static inline struct atsc_text *
+ atsc_rrt_dimension_value_abbrev_rating_value_text(struct atsc_rrt_dimension_value *value)
+{
+ if (value->abbrev_rating_value_length == 0)
+ return NULL;
+
+ return (struct atsc_text*)(((uint8_t*) value) + sizeof(struct atsc_rrt_dimension_value));
+}
+
+/**
+ * Accessor for the part2 field of an atsc_rrt_dimension_value.
+ *
+ * @param value atsc_rrt_dimension_value pointer.
+ * @return struct atsc_rrt_dimension_value_part2 pointer.
+ */
+static inline struct atsc_rrt_dimension_value_part2 *atsc_rrt_dimension_value_part2(struct atsc_rrt_dimension_value *value)
+{
+ return (struct atsc_rrt_dimension_value_part2 *)
+ (((uint8_t*) value) +
+ sizeof(struct atsc_rrt_dimension_value) +
+ value->abbrev_rating_value_length);
+}
+
+/**
+ * Accessor for the rating_value_text field of an atsc_rrt_dimension_value_part2.
+ *
+ * @param part2 atsc_rrt_dimension_value_part2 pointer.
+ * @return struct atsc_text pointer.
+ */
+static inline struct atsc_text *atsc_rrt_dimension_value_part2_rating_value_text(struct atsc_rrt_dimension_value_part2 *part2)
+{
+ if (part2->rating_value_length == 0)
+ return NULL;
+
+ return (struct atsc_text*)(((uint8_t*) part2) + sizeof(struct atsc_rrt_dimension_value_part2));
+}
+
+/**
+ * Accessor for the third part of an atsc_rrt_section.
+ *
+ * @param part2 atsc_rrt_section_part2 pointer.
+ * @return atsc_rrt_section_part3 pointer.
+ */
+static inline struct atsc_rrt_section_part3 *
+ atsc_rrt_section_part3(struct atsc_rrt_section_part2 *part2)
+{
+ int pos = sizeof(struct atsc_rrt_section_part2);
+
+ struct atsc_rrt_dimension *cur_dimension;
+ int idx;
+ atsc_rrt_section_dimensions_for_each(part2, cur_dimension, idx) {
+ pos += sizeof(struct atsc_rrt_dimension);
+ pos += cur_dimension->dimension_name_length;
+ pos += sizeof(struct atsc_rrt_dimension_part2);
+
+ // now we need to iterate over the values. yuck
+ struct atsc_rrt_dimension_part2 *dpart2 = atsc_rrt_dimension_part2(cur_dimension);
+ struct atsc_rrt_dimension_value *cur_value;
+ int vidx;
+ atsc_rrt_dimension_part2_values_for_each(dpart2, cur_value, vidx) {
+ pos += sizeof(struct atsc_rrt_dimension_value);
+ pos += cur_value->abbrev_rating_value_length;
+
+ struct atsc_rrt_dimension_value_part2 *vpart2 = atsc_rrt_dimension_value_part2(cur_value);
+ pos += sizeof(struct atsc_rrt_dimension_value_part2);
+ pos += vpart2->rating_value_length;
+ }
+ }
+
+ return (struct atsc_rrt_section_part3 *) (((uint8_t*) part2) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_rrt_section structure.
+ *
+ * @param part3 atsc_rrt_section_part3 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_rrt_section_part3_descriptors_for_each(part3, pos) \
+ for ((pos) = atsc_rrt_section_part3_descriptors_first(part3); \
+ (pos); \
+ (pos) = atsc_rrt_section_part3_descriptors_next(part3, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_rrt_dimension *
+ atsc_rrt_section_dimensions_first(struct atsc_rrt_section_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_rrt_section_part2);
+
+ if (part2->dimensions_defined == 0)
+ return NULL;
+
+ return (struct atsc_rrt_dimension*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct atsc_rrt_dimension *
+ atsc_rrt_section_dimensions_next(struct atsc_rrt_section_part2 *part2,
+ struct atsc_rrt_dimension *pos,
+ int idx)
+{
+ if (idx >= part2->dimensions_defined)
+ return NULL;
+
+ struct atsc_rrt_dimension_part2 *dpart2 = atsc_rrt_dimension_part2(pos);
+ int len = sizeof(struct atsc_rrt_dimension_part2);
+
+ // now we need to iterate over the values. yuck
+ struct atsc_rrt_dimension_value *cur_value;
+ int vidx;
+ atsc_rrt_dimension_part2_values_for_each(dpart2, cur_value, vidx) {
+ len += sizeof(struct atsc_rrt_dimension_value);
+ len += cur_value->abbrev_rating_value_length;
+
+ struct atsc_rrt_dimension_value_part2 *vpart2 = atsc_rrt_dimension_value_part2(cur_value);
+ len += sizeof(struct atsc_rrt_dimension_value_part2);
+ len += vpart2->rating_value_length;
+ }
+
+ return (struct atsc_rrt_dimension *) (((uint8_t*) dpart2) + len);
+}
+
+static inline struct atsc_rrt_dimension_value *
+ atsc_rrt_dimension_part2_values_first(struct atsc_rrt_dimension_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_rrt_dimension_part2);
+
+ if (part2->values_defined == 0)
+ return NULL;
+
+ return (struct atsc_rrt_dimension_value*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct atsc_rrt_dimension_value *
+ atsc_rrt_dimension_part2_values_next(struct atsc_rrt_dimension_part2 *part2,
+ struct atsc_rrt_dimension_value *pos,
+ int idx)
+{
+ if (idx >= part2->values_defined)
+ return NULL;
+
+ struct atsc_rrt_dimension_value_part2 *vpart2 = atsc_rrt_dimension_value_part2(pos);
+ int len = sizeof(struct atsc_rrt_dimension_value_part2);
+ len += vpart2->rating_value_length;
+
+ return (struct atsc_rrt_dimension_value *) (((uint8_t*) vpart2) + len);
+}
+
+static inline struct descriptor *
+ atsc_rrt_section_part3_descriptors_first(struct atsc_rrt_section_part3 *part3)
+{
+ size_t pos = sizeof(struct atsc_rrt_section_part3);
+
+ if (part3->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part3) + pos);
+}
+
+static inline struct descriptor *
+ atsc_rrt_section_part3_descriptors_next(struct atsc_rrt_section_part3 *part3,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part3 + sizeof(struct atsc_rrt_section_part3),
+ part3->descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/section.h b/lib/libucsi/atsc/section.h
new file mode 100644
index 0000000..23d59ea
--- /dev/null
+++ b/lib/libucsi/atsc/section.h
@@ -0,0 +1,84 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/section.h>
+#include <libucsi/atsc/mgt_section.h>
+#include <libucsi/atsc/tvct_section.h>
+#include <libucsi/atsc/cvct_section.h>
+#include <libucsi/atsc/rrt_section.h>
+#include <libucsi/atsc/eit_section.h>
+#include <libucsi/atsc/ett_section.h>
+#include <libucsi/atsc/stt_section.h>
+#include <libucsi/atsc/dcct_section.h>
+#include <libucsi/atsc/dccsct_section.h>
+
+#ifndef _UCSI_ATSC_SECTION_H
+#define _UCSI_ATSC_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define ATSC_BASE_PID 0x1ffb
+
+/**
+ * Enumeration of ATSC section tags.
+ */
+enum atsc_section_tag {
+ stag_atsc_master_guide = 0xc7,
+ stag_atsc_terrestrial_virtual_channel = 0xc8,
+ stag_atsc_cable_virtual_channel = 0xc9,
+ stag_atsc_rating_region = 0xca,
+ stag_atsc_event_information = 0xcb,
+ stag_atsc_extended_text = 0xcc,
+ stag_atsc_system_time = 0xcd,
+};
+
+/**
+ * ATSC specific PSIP section structure.
+ */
+struct atsc_section_psip {
+ struct section_ext ext_head;
+ uint8_t protocol_version;
+} __ucsi_packed;
+
+/**
+ * Decode a PSIP section structure.
+ *
+ * @param section_ext Pointer to the processed section_ext structure.
+ * @return Pointer to the parsed section_psip structure, or NULL if invalid.
+ */
+static inline struct atsc_section_psip *atsc_section_psip_decode(struct section_ext *section_ext)
+{
+ size_t len = section_ext_length(section_ext);
+ if (len < sizeof(struct atsc_section_psip)) {
+ return NULL;
+ }
+
+ return (struct atsc_section_psip *) section_ext;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/service_location_descriptor.h b/lib/libucsi/atsc/service_location_descriptor.h
new file mode 100644
index 0000000..aad5b4a
--- /dev/null
+++ b/lib/libucsi/atsc/service_location_descriptor.h
@@ -0,0 +1,141 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_SERVICE_LOCATION_DESCRIPTOR
+#define _UCSI_ATSC_SERVICE_LOCATION_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+enum atsc_stream_types {
+ ATSC_STREAM_TYPE_VIDEO = 0x02,
+ ATSC_STREAM_TYPE_AUDIO = 0x81,
+};
+
+/**
+ * atsc_service_location_descriptor structure.
+ */
+struct atsc_service_location_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint16_t reserved : 3; ,
+ uint16_t PCR_PID :13; );
+ uint8_t number_elements;
+ /* struct atsc_service_location_element elements[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the elements field of an atsc_service_location_descriptor.
+ */
+struct atsc_caption_service_location_element {
+ uint8_t stream_type;
+ EBIT2(uint16_t reserved : 3; ,
+ uint16_t elementary_PID :13; );
+ iso639lang_t language_code;
+} __ucsi_packed;
+
+/**
+ * Process an atsc_service_location_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_service_location_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_service_location_descriptor*
+ atsc_service_location_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_service_location_descriptor *ret =
+ (struct atsc_service_location_descriptor *) d;
+ uint8_t *buf = (uint8_t*) d + 2;
+ int pos = 0;
+ int idx;
+
+ if (d->len < 3)
+ return NULL;
+ bswap16(buf + pos);
+ pos+=3;
+
+ for(idx = 0; idx < ret->number_elements; idx++) {
+ if (d->len < (pos + sizeof(struct atsc_caption_service_entry)))
+ return NULL;
+
+ bswap16(buf+pos+1);
+
+ pos += sizeof(struct atsc_caption_service_entry);
+ }
+
+ return (struct atsc_service_location_descriptor*) d;
+}
+
+/**
+ * Iterator for elements field of a atsc_service_location_descriptor.
+ *
+ * @param d atsc_service_location_descriptor pointer.
+ * @param pos Variable holding a pointer to the current atsc_service_location_element.
+ * @param idx Integer used to count which dimension we are in.
+ */
+#define atsc_service_location_descriptor_elements_for_each(d, pos, idx) \
+ for ((pos) = atsc_service_location_descriptor_elements_first(d), idx=0; \
+ (pos); \
+ (pos) = atsc_service_location_descriptor_elements_next(d, pos, ++idx))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_caption_service_location_element*
+ atsc_service_location_descriptor_elements_first(struct atsc_service_location_descriptor *d)
+{
+ if (d->number_elements == 0)
+ return NULL;
+
+ return (struct atsc_caption_service_location_element *)
+ ((uint8_t*) d + sizeof(struct atsc_service_location_descriptor));
+}
+
+static inline struct atsc_caption_service_location_element*
+ atsc_service_location_descriptor_elements_next(struct atsc_service_location_descriptor *d,
+ struct atsc_caption_service_location_element *pos,
+ int idx)
+{
+ uint8_t *next = (uint8_t *) pos + sizeof(struct atsc_caption_service_location_element);
+
+ if (idx >= d->number_elements)
+ return NULL;
+ return (struct atsc_caption_service_location_element *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/stt_section.c b/lib/libucsi/atsc/stt_section.c
new file mode 100644
index 0000000..23ddd76
--- /dev/null
+++ b/lib/libucsi/atsc/stt_section.c
@@ -0,0 +1,42 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/stt_section.h>
+
+struct atsc_stt_section *atsc_stt_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t *buf = (uint8_t *) psip;
+ size_t pos = sizeof(struct atsc_section_psip);
+ size_t len = section_ext_length(&(psip->ext_head));
+
+ if (len < sizeof(struct atsc_stt_section))
+ return NULL;
+
+ bswap32(buf + pos);
+ pos += 5;
+ bswap16(buf + pos);
+ pos += 2;
+
+ if (verify_descriptors(buf + pos, len - sizeof(struct atsc_stt_section)))
+ return NULL;
+
+ return (struct atsc_stt_section *) psip;
+}
diff --git a/lib/libucsi/atsc/stt_section.h b/lib/libucsi/atsc/stt_section.h
new file mode 100644
index 0000000..79db5a1
--- /dev/null
+++ b/lib/libucsi/atsc/stt_section.h
@@ -0,0 +1,105 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_STT_SECTION_H
+#define _UCSI_ATSC_STT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+#include <libucsi/atsc/types.h>
+
+/**
+ * atsc_stt_section structure.
+ */
+struct atsc_stt_section {
+ struct atsc_section_psip head;
+
+ atsctime_t system_time;
+ uint8_t gps_utc_offset;
+ EBIT4(uint16_t DS_status : 1; ,
+ uint16_t reserved : 2; ,
+ uint16_t DS_day_of_month : 5; ,
+ uint16_t DS_hour : 8; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process a atsc_stt_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_stt_section pointer, or NULL on error.
+ */
+struct atsc_stt_section *atsc_stt_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Iterator for the services field in a atsc_stt_section.
+ *
+ * @param stt atsc_stt_section pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_stt_section_descriptors_for_each(stt, pos) \
+ for ((pos) = atsc_stt_section_descriptors_first(stt); \
+ (pos); \
+ (pos) = atsc_stt_section_descriptors_next(stt, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ atsc_stt_section_descriptors_first(struct atsc_stt_section *stt)
+{
+ size_t pos = sizeof(struct atsc_stt_section);
+
+ if (pos >= section_ext_length(&stt->head.ext_head))
+ return NULL;
+
+ return (struct descriptor*) ((uint8_t *) stt + pos);
+}
+
+static inline struct descriptor *
+ atsc_stt_section_descriptors_next(struct atsc_stt_section *stt,
+ struct descriptor *pos)
+{
+ int len = section_ext_length(&stt->head.ext_head);
+ len -= sizeof(struct atsc_stt_section);
+
+ return next_descriptor((uint8_t*) stt + sizeof(struct atsc_stt_section),
+ len,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/stuffing_descriptor.h b/lib/libucsi/atsc/stuffing_descriptor.h
new file mode 100644
index 0000000..777c282
--- /dev/null
+++ b/lib/libucsi/atsc/stuffing_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_atsc@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_STUFFING_DESCRIPTOR
+#define _UCSI_ATSC_STUFFING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * atsc_stuffing_descriptor.
+ */
+struct atsc_stuffing_descriptor {
+ struct descriptor d;
+
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process a atsc_stuffing_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return atsc_stuffing_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_stuffing_descriptor*
+ atsc_stuffing_descriptor_codec(struct descriptor* d)
+{
+ return (struct atsc_stuffing_descriptor*) d;
+}
+
+/**
+ * Retrieve a pointer to the data field of a atsc_stuffing_descriptor.
+ *
+ * @param d atsc_stuffing_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ atsc_stuffing_descriptor_data(struct atsc_stuffing_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct atsc_stuffing_descriptor);
+}
+
+/**
+ * Calculate length of the data field of a atsc_stuffing_descriptor.
+ *
+ * @param d atsc_stuffing_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ atsc_stuffing_descriptor_data_length(struct atsc_stuffing_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/time_shifted_service_descriptor.h b/lib/libucsi/atsc/time_shifted_service_descriptor.h
new file mode 100644
index 0000000..599e66d
--- /dev/null
+++ b/lib/libucsi/atsc/time_shifted_service_descriptor.h
@@ -0,0 +1,136 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_TIME_SHIFTED_SERVICE_DESCRIPTOR
+#define _UCSI_ATSC_TIME_SHIFTED_SERVICE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * atsc_time_shifted_service_descriptor structure.
+ */
+struct atsc_time_shifted_service_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 3; ,
+ uint8_t number_of_services : 5; );
+ /* struct atsc_time_shifted_service services[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the services field of an atsc_time_shifted_service_descriptor.
+ */
+struct atsc_time_shifted_service {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t time_shift :10; );
+ EBIT3(uint32_t reserved2 : 4; ,
+ uint32_t major_channel_number :10; ,
+ uint32_t minor_channel_number :10; );
+} __ucsi_packed;
+
+/**
+ * Process an atsc_time_shifted_service_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return atsc_time_shifted_service_descriptor pointer, or NULL on error.
+ */
+static inline struct atsc_time_shifted_service_descriptor*
+ atsc_time_shifted_service_descriptor_codec(struct descriptor* d)
+{
+ struct atsc_time_shifted_service_descriptor *ret =
+ (struct atsc_time_shifted_service_descriptor *) d;
+ uint8_t *buf = (uint8_t*) d + 2;
+ int pos = 0;
+ int idx;
+
+ if (d->len < 1)
+ return NULL;
+ pos++;
+
+ for(idx = 0; idx < ret->number_of_services; idx++) {
+ if (d->len < (pos + sizeof(struct atsc_time_shifted_service)))
+ return NULL;
+
+ bswap16(buf+pos);
+ bswap24(buf+pos+2);
+
+ pos += sizeof(struct atsc_time_shifted_service);
+ }
+
+ return (struct atsc_time_shifted_service_descriptor*) d;
+}
+
+/**
+ * Iterator for services field of a atsc_time_shifted_service_descriptor.
+ *
+ * @param d atsc_time_shifted_service_descriptor pointer.
+ * @param pos Variable holding a pointer to the current atsc_service_location_element.
+ * @param idx Integer used to count which service we are in.
+ */
+#define atsc_time_shifted_service_descriptor_services_for_each(d, pos, idx) \
+ for ((pos) = atsc_time_shifted_service_descriptor_services_first(d), idx=0; \
+ (pos); \
+ (pos) = atsc_time_shifted_service_descriptor_services_next(d, pos, ++idx))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_time_shifted_service*
+ atsc_time_shifted_service_descriptor_services_first(struct atsc_time_shifted_service_descriptor *d)
+{
+ if (d->number_of_services == 0)
+ return NULL;
+
+ return (struct atsc_time_shifted_service *)
+ ((uint8_t*) d + sizeof(struct atsc_time_shifted_service_descriptor));
+}
+
+static inline struct atsc_time_shifted_service*
+ atsc_time_shifted_service_descriptor_services_next(struct atsc_time_shifted_service_descriptor *d,
+ struct atsc_time_shifted_service *pos,
+ int idx)
+{
+ uint8_t *next = (uint8_t *) pos + sizeof(struct atsc_time_shifted_service);
+
+ if (idx >= d->number_of_services)
+ return NULL;
+ return (struct atsc_time_shifted_service *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/tvct_section.c b/lib/libucsi/atsc/tvct_section.c
new file mode 100644
index 0000000..d187414
--- /dev/null
+++ b/lib/libucsi/atsc/tvct_section.c
@@ -0,0 +1,81 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/atsc/tvct_section.h>
+
+struct atsc_tvct_section *atsc_tvct_section_codec(struct atsc_section_psip *psip)
+{
+ uint8_t * buf = (uint8_t *) psip;
+ size_t pos = sizeof(struct atsc_section_psip);
+ size_t len = section_ext_length(&(psip->ext_head));
+ int idx;
+ struct atsc_tvct_section *tvct = (struct atsc_tvct_section *) psip;
+
+ if (len < sizeof(struct atsc_tvct_section))
+ return NULL;
+
+ pos++;
+
+ for(idx =0; idx < tvct->num_channels_in_section; idx++) {
+
+ if ((pos + sizeof(struct atsc_tvct_channel)) > len)
+ return NULL;
+ struct atsc_tvct_channel *channel = (struct atsc_tvct_channel *) (buf+pos);
+
+ pos += 7*2;
+
+ bswap32(buf+pos);
+ bswap32(buf+pos+4);
+ bswap16(buf+pos+8);
+ bswap16(buf+pos+10);
+ bswap16(buf+pos+12);
+ bswap16(buf+pos+14);
+ bswap16(buf+pos+16);
+ pos+=18;
+
+ if ((pos + channel->descriptors_length) > len)
+ return NULL;
+ if (verify_descriptors(buf + pos, channel->descriptors_length))
+ return NULL;
+
+ pos += channel->descriptors_length;
+ }
+
+ if ((pos + sizeof(struct atsc_tvct_section_part2)) > len)
+ return NULL;
+ struct atsc_tvct_section_part2 *part2 = (struct atsc_tvct_section_part2 *) (buf+pos);
+
+ bswap16(buf+pos);
+ pos+=2;
+
+ if ((pos + part2->descriptors_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, part2->descriptors_length))
+ return NULL;
+
+ pos += part2->descriptors_length;
+
+ if (pos != len)
+ return NULL;
+
+ return (struct atsc_tvct_section *) psip;
+}
diff --git a/lib/libucsi/atsc/tvct_section.h b/lib/libucsi/atsc/tvct_section.h
new file mode 100644
index 0000000..77bc5f4
--- /dev/null
+++ b/lib/libucsi/atsc/tvct_section.h
@@ -0,0 +1,227 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_TVCT_SECTION_H
+#define _UCSI_ATSC_TVCT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/atsc/section.h>
+
+/**
+ * atsc_tvct_section structure.
+ */
+struct atsc_tvct_section {
+ struct atsc_section_psip head;
+
+ uint8_t num_channels_in_section;
+ /* struct atsc_tvct_channel channels[] */
+ /* struct atsc_tvct_channel_part2 part2 */
+} __ucsi_packed;
+
+struct atsc_tvct_channel {
+ uint16_t short_name[7]; // UTF-16 network ordered
+ EBIT4(uint32_t reserved : 4; ,
+ uint32_t major_channel_number :10; ,
+ uint32_t minor_channel_number :10; ,
+ uint32_t modulation_mode : 8; );
+ uint32_t carrier_frequency;
+ uint16_t channel_TSID;
+ uint16_t program_number;
+ EBIT7(uint16_t ETM_location : 2; ,
+ uint16_t access_controlled : 1; ,
+ uint16_t hidden : 1; ,
+ uint16_t reserved1 : 2; ,
+ uint16_t hide_guide : 1; ,
+ uint16_t reserved2 : 3; ,
+ uint16_t service_type : 6; );
+ uint16_t source_id;
+ EBIT2(uint16_t reserved3 : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct atsc_tvct_section_part2 {
+ EBIT2(uint16_t reserved : 6; ,
+ uint16_t descriptors_length :10; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+static inline struct atsc_tvct_channel *atsc_tvct_section_channels_first(struct atsc_tvct_section *tvct);
+static inline struct atsc_tvct_channel *
+ atsc_tvct_section_channels_next(struct atsc_tvct_section *tvct, struct atsc_tvct_channel *pos, int idx);
+
+/**
+ * Process a atsc_tvct_section.
+ *
+ * @param section Pointer to an atsc_section_psip structure.
+ * @return atsc_tvct_section pointer, or NULL on error.
+ */
+struct atsc_tvct_section *atsc_tvct_section_codec(struct atsc_section_psip *section);
+
+/**
+ * Accessor for the transport_stream_id field of a TVCT.
+ *
+ * @param tvct TVCT pointer.
+ * @return The transport_stream_id.
+ */
+static inline uint16_t atsc_tvct_section_transport_stream_id(struct atsc_tvct_section *tvct)
+{
+ return tvct->head.ext_head.table_id_ext;
+}
+
+/**
+ * Iterator for the channels field in an atsc_tvct_section.
+ *
+ * @param mgt atsc_tvct_section pointer.
+ * @param pos Variable containing a pointer to the current atsc_tvct_channel.
+ * @param idx Integer used to count which channel we in.
+ */
+#define atsc_tvct_section_channels_for_each(mgt, pos, idx) \
+ for ((pos) = atsc_tvct_section_channels_first(mgt), idx=0; \
+ (pos); \
+ (pos) = atsc_tvct_section_channels_next(mgt, pos, ++idx))
+
+/**
+ * Iterator for the descriptors field in a atsc_tvct_channel structure.
+ *
+ * @param channel atsc_tvct_channel pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_tvct_channel_descriptors_for_each(channel, pos) \
+ for ((pos) = atsc_tvct_channel_descriptors_first(channel); \
+ (pos); \
+ (pos) = atsc_tvct_channel_descriptors_next(channel, pos))
+
+/**
+ * Accessor for the second part of an atsc_tvct_section.
+ *
+ * @param mgt atsc_tvct_section pointer.
+ * @return atsc_tvct_section_part2 pointer.
+ */
+static inline struct atsc_tvct_section_part2 *
+ atsc_tvct_section_part2(struct atsc_tvct_section *mgt)
+{
+ int pos = sizeof(struct atsc_tvct_section);
+
+ struct atsc_tvct_channel *cur_channel;
+ int idx;
+ atsc_tvct_section_channels_for_each(mgt, cur_channel, idx) {
+ pos += sizeof(struct atsc_tvct_channel);
+ pos += cur_channel->descriptors_length;
+ }
+
+ return (struct atsc_tvct_section_part2 *) (((uint8_t*) mgt) + pos);
+}
+
+/**
+ * Iterator for the descriptors field in a atsc_tvct_section structure.
+ *
+ * @param part2 atsc_tvct_section_part2 pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define atsc_tvct_section_part2_descriptors_for_each(part2, pos) \
+ for ((pos) = atsc_tvct_section_part2_descriptors_first(part2); \
+ (pos); \
+ (pos) = atsc_tvct_section_part2_descriptors_next(part2, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_tvct_channel *
+ atsc_tvct_section_channels_first(struct atsc_tvct_section *tvct)
+{
+ size_t pos = sizeof(struct atsc_tvct_section);
+
+ if (tvct->num_channels_in_section == 0)
+ return NULL;
+
+ return (struct atsc_tvct_channel*) (((uint8_t *) tvct) + pos);
+}
+
+static inline struct atsc_tvct_channel *
+ atsc_tvct_section_channels_next(struct atsc_tvct_section *tvct,
+ struct atsc_tvct_channel *pos,
+ int idx)
+{
+ if (idx >= tvct->num_channels_in_section)
+ return NULL;
+
+ return (struct atsc_tvct_channel *)
+ (((uint8_t*) pos) + sizeof(struct atsc_tvct_channel) + pos->descriptors_length);
+}
+
+static inline struct descriptor *
+ atsc_tvct_channel_descriptors_first(struct atsc_tvct_channel *channel)
+{
+ size_t pos = sizeof(struct atsc_tvct_channel);
+
+ if (channel->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) channel) + pos);
+}
+
+static inline struct descriptor *
+ atsc_tvct_channel_descriptors_next(struct atsc_tvct_channel *channel,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) channel + sizeof(struct atsc_tvct_channel),
+ channel->descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ atsc_tvct_section_part2_descriptors_first(struct atsc_tvct_section_part2 *part2)
+{
+ size_t pos = sizeof(struct atsc_tvct_section_part2);
+
+ if (part2->descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor*) (((uint8_t *) part2) + pos);
+}
+
+static inline struct descriptor *
+ atsc_tvct_section_part2_descriptors_next(struct atsc_tvct_section_part2 *part2,
+ struct descriptor *pos)
+{
+ return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_tvct_section_part2),
+ part2->descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/atsc/types.c b/lib/libucsi/atsc/types.c
new file mode 100644
index 0000000..8f4b7ea
--- /dev/null
+++ b/lib/libucsi/atsc/types.c
@@ -0,0 +1,71 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <string.h>
+#include "libucsi/atsc/types.h"
+
+/* GPS epoch == unix time_t at 06/Jan/1980 */
+#define GPS_EPOCH 315964800
+
+
+int atsc_text_validate(uint8_t *buf, int len)
+{
+ int i;
+ int j;
+ int number_strings;
+ int number_segments;
+ int number_bytes;
+ int pos = 0;
+
+ if (len == 0)
+ return 0;
+ number_strings = buf[pos];
+ pos++;
+
+ for(i=0; i< number_strings; i++) {
+ if (len < (pos+4))
+ return -1;
+ number_segments = buf[pos+3];
+ pos+=4;
+
+ for(j=0; j < number_segments; j++) {
+ if (len < (pos+3))
+ return -1;
+ number_bytes = buf[pos+2];
+ pos+=3;
+
+ if (len < (pos + number_bytes))
+ return -1;
+ pos += number_bytes;
+ }
+ }
+
+ return 0;
+}
+
+time_t atsctime_to_unixtime(atsctime_t atsc)
+{
+ return atsc + GPS_EPOCH;
+}
+
+atsctime_t unixtime_to_atsctime(time_t t)
+{
+ return t - GPS_EPOCH;
+}
diff --git a/lib/libucsi/atsc/types.h b/lib/libucsi/atsc/types.h
new file mode 100644
index 0000000..4d4b802
--- /dev/null
+++ b/lib/libucsi/atsc/types.h
@@ -0,0 +1,227 @@
+ /*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_ATSC_TYPES_H
+#define _UCSI_ATSC_TYPES_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+#include <time.h>
+#include <libucsi/types.h>
+
+enum atsc_vct_modulation {
+ ATSC_VCT_MODULATION_ANALOG = 0x01,
+ ATSC_VCT_MODULATION_SCTE_MODE1 = 0x02,
+ ATSC_VCT_MODULATION_SCTE_MODE2 = 0x03,
+ ATSC_VCT_MODULATION_8VSB = 0x04,
+ ATSC_VCT_MODULATION_16VSB = 0x05,
+};
+
+enum atsc_vct_service_type {
+ ATSC_VCT_SERVICE_TYPE_ANALOG = 0x01,
+ ATSC_VCT_SERVICE_TYPE_TV = 0x02,
+ ATSC_VCT_SERVICE_TYPE_AUDIO = 0x03,
+ ATSC_VCT_SERVICE_TYPE_DATA = 0x04,
+};
+
+enum atsc_etm_location {
+ ATSC_VCT_ETM_NONE = 0x00,
+ ATSC_VCT_ETM_IN_THIS_PTC = 0x01,
+ ATSC_VCT_ETM_IN_CHANNEL_TSID = 0x02,
+};
+
+enum atsc_text_compress_type {
+ ATSC_TEXT_COMPRESS_NONE = 0x00,
+ ATSC_TEXT_COMPRESS_PROGRAM_TITLE = 0x01,
+ ATSC_TEXT_COMPRESS_PROGRAM_DESCRIPTION = 0x02,
+};
+
+enum atsc_text_segment_mode {
+ ATSC_TEXT_SEGMENT_MODE_UNICODE_RANGE_MIN = 0x00,
+ ATSC_TEXT_SEGMENT_MODE_UNICODE_RANGE_MAX = 0x33,
+ ATSC_TEXT_SEGMENT_MODE_SCSU = 0x3e,
+ ATSC_TEXT_SEGMENT_MODE_UTF16 = 0x3f,
+ ATSC_TEXT_SEGMENT_MODE_TAIWAN_BITMAP = 0x40,
+ ATSC_TEXT_SEGMENT_MODE_TAIWAN_CODEWORD_BITMAP = 0x41,
+};
+
+typedef uint32_t atsctime_t;
+
+struct atsc_text {
+ uint8_t number_strings;
+ /* struct atsc_text_string strings[] */
+};
+
+struct atsc_text_string {
+ iso639lang_t language_code;
+ uint8_t number_segments;
+ /* struct atsc_text_string_segment segments[] */
+};
+
+struct atsc_text_string_segment {
+ uint8_t compression_type;
+ uint8_t mode;
+ uint8_t number_bytes;
+ /* uint8_t bytes[] */
+};
+
+/**
+ * Iterator for strings field of an atsc_text structure.
+ *
+ * @param txt atsc_text pointer.
+ * @param pos Variable holding a pointer to the current atsc_text_string.
+ * @param idx Iterator variable.
+ */
+#define atsc_text_strings_for_each(txt, pos, idx) \
+ for ((pos) = atsc_text_strings_first(txt), idx=0; \
+ (pos); \
+ (pos) = atsc_text_strings_next(txt, pos, ++idx))
+
+/**
+ * Iterator for segments field of an atsc_text_string structure.
+ *
+ * @param str atsc_text_string pointer.
+ * @param pos Variable holding a pointer to the current atsc_text_string_segment.
+ * @param idx Iterator variable.
+ */
+#define atsc_text_string_segments_for_each(str, pos, idx) \
+ for ((pos) = atsc_text_string_segments_first(str), idx=0; \
+ (pos); \
+ (pos) = atsc_text_string_segments_next(str, pos, ++idx))
+
+/**
+ * Accessor for the bytes field of an atsc_text_string_segment.
+ *
+ * @param seg atsc_text_string_segment pointer.
+ * @return Pointer to the bytes.
+ */
+static inline uint8_t*
+ atsc_text_string_segment_bytes(struct atsc_text_string_segment *d)
+{
+ return ((uint8_t*) d) + sizeof(struct atsc_text_string_segment);
+}
+
+/**
+ * Validate a buffer containing an atsc_text structure.
+ *
+ * @param buf Start of the atsc_text structure.
+ * @param len Length in bytes of the buffer.
+ * @return 0 if valid, nonzero if not.
+ */
+extern int atsc_text_validate(uint8_t *buf, int len);
+
+/**
+ * Decodes an atsc_text_segment with mode < 0x3e. Decompression of the ATSC text encoding IS
+ * supported. The output text will be in the UTF-8 encoding.
+ *
+ * @param segment Pointer to the segment to decode.
+ * @param destbuf Pointer to the malloc()ed buffer to append text to (pass NULL if none).
+ * @param destbufsize Size of destbuf in bytes.
+ * @param destbufpos Position within destbuf. This will be updated to point after the end of the
+ * string on exit.
+ * @return New value of destbufpos, or < 0 on error.
+ */
+extern int atsc_text_segment_decode(struct atsc_text_string_segment *segment,
+ uint8_t **destbuf, size_t *destbufsize, size_t *destbufpos);
+
+/**
+ * Convert from ATSC time to unix time_t.
+ *
+ * @param atsc ATSC time.
+ * @return The time value.
+ */
+extern time_t atsctime_to_unixtime(atsctime_t atsc);
+
+/**
+ * Convert from unix time_t to atsc time.
+ *
+ * @param t unix time_t.
+ * @return The atsc time value.
+ */
+extern atsctime_t unixtime_to_atsctime(time_t t);
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct atsc_text_string*
+ atsc_text_strings_first(struct atsc_text *txt)
+{
+ if (txt->number_strings == 0)
+ return NULL;
+
+ return (struct atsc_text_string *)
+ ((uint8_t*) txt + sizeof(struct atsc_text));
+}
+
+static inline struct atsc_text_string*
+ atsc_text_strings_next(struct atsc_text *txt, struct atsc_text_string *pos, int idx)
+{
+ int i;
+ uint8_t *buf;
+
+ if (idx >= txt->number_strings)
+ return NULL;
+
+ buf = ((uint8_t*) pos) + sizeof(struct atsc_text_string);
+ for(i=0; i < pos->number_segments; i++) {
+ struct atsc_text_string_segment *seg =
+ (struct atsc_text_string_segment *) buf;
+
+ buf += sizeof(struct atsc_text_string_segment);
+ buf += seg->number_bytes;
+ }
+
+ return (struct atsc_text_string *) buf;
+}
+
+static inline struct atsc_text_string_segment*
+ atsc_text_string_segments_first(struct atsc_text_string *str)
+{
+ if (str->number_segments == 0)
+ return NULL;
+
+ return (struct atsc_text_string_segment *)
+ ((uint8_t*) str + sizeof(struct atsc_text_string));
+}
+
+static inline struct atsc_text_string_segment*
+ atsc_text_string_segments_next(struct atsc_text_string *str,
+ struct atsc_text_string_segment *pos, int idx)
+{
+ if (idx >= str->number_segments)
+ return NULL;
+
+ return (struct atsc_text_string_segment *)
+ (((uint8_t*) pos) + sizeof(struct atsc_text_string_segment) + pos->number_bytes);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/crc32.c b/lib/libucsi/crc32.c
new file mode 100644
index 0000000..dc1de5c
--- /dev/null
+++ b/lib/libucsi/crc32.c
@@ -0,0 +1,89 @@
+/**
+ * crc32 calculation routines.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdint.h>
+
+uint32_t crc32tbl[] =
+{
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
diff --git a/lib/libucsi/crc32.h b/lib/libucsi/crc32.h
new file mode 100644
index 0000000..7d781ce
--- /dev/null
+++ b/lib/libucsi/crc32.h
@@ -0,0 +1,58 @@
+/**
+ * crc32 calculation routines.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_CRC32_H
+#define _UCSI_CRC32_H 1
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define CRC32_INIT (~0)
+
+extern uint32_t crc32tbl[];
+
+/**
+ * Calculate a CRC32 over a piece of data.
+ *
+ * @param crc Current CRC value (use CRC32_INIT for first call).
+ * @param buf Buffer to calculate over.
+ * @param len Number of bytes.
+ * @return Calculated CRC.
+ */
+static inline uint32_t crc32(uint32_t crc, uint8_t* buf, size_t len)
+{
+ size_t i;
+
+ for (i=0; i< len; i++) {
+ crc = (crc << 8) ^ crc32tbl[((crc >> 24) ^ buf[i]) & 0xff];
+ }
+
+ return crc;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/descriptor.h b/lib/libucsi/descriptor.h
new file mode 100644
index 0000000..606e45d
--- /dev/null
+++ b/lib/libucsi/descriptor.h
@@ -0,0 +1,129 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DESCRIPTOR_H
+#define _UCSI_DESCRIPTOR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/endianops.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/**
+ * Generic descriptor header.
+ */
+struct descriptor {
+ uint8_t tag;
+ uint8_t len;
+} __ucsi_packed;
+
+/**
+ * Retreive pointer to the next descriptor structure.
+ *
+ * @param buf The buffer of descriptors.
+ * @param len Size of the buffer.
+ * @param pos Current descriptor.
+ * @return Pointer to next descriptor, or NULL if there are none.
+ */
+static inline struct descriptor *
+ next_descriptor(uint8_t * buf, size_t len, struct descriptor * pos)
+{
+ uint8_t* next;
+
+ if (pos == NULL)
+ return NULL;
+
+ next = (uint8_t*) pos + 2 + pos->len;
+ if (next >= buf + len)
+ return NULL;
+
+ return (struct descriptor *) next;
+}
+
+
+/**
+ * The unknown descriptor.
+ */
+struct unknown_descriptor {
+ struct descriptor d;
+
+ /* uint8_t data [] */
+} __ucsi_packed;
+
+/**
+ * Retrieve pointer to the unknown descriptor's data field.
+ *
+ * @param d The descriptor.
+ * @return Pointer to the data field.
+ */
+static inline uint8_t *
+ unknown_descriptor_data(struct unknown_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct unknown_descriptor);
+}
+
+/**
+ * Retrieve size of unknown descriptor's data field.
+ *
+ * @param d The descriptor.
+ * @return Size of data field in bytes.
+ */
+static inline int
+ unknown_descriptor_data_size(struct unknown_descriptor *d)
+{
+ return d->d.len;
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline int verify_descriptors(uint8_t * buf, size_t len)
+{
+ size_t pos = 0;
+
+ while (pos < len) {
+ if ((pos + 2) > len)
+ return -1;
+
+ pos += 2 + buf[pos+1];
+ }
+
+ if (pos != len)
+ return -1;
+
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/Makefile b/lib/libucsi/dvb/Makefile
new file mode 100644
index 0000000..78876dc
--- /dev/null
+++ b/lib/libucsi/dvb/Makefile
@@ -0,0 +1,121 @@
+# Makefile for linuxtv.org dvb-apps/lib/libucsi/dvb
+
+.PHONY: sub-error-dvb
+
+sub-error-dvb:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += dvb/bat_section.o \
+ dvb/dit_section.o \
+ dvb/eit_section.o \
+ dvb/int_section.o \
+ dvb/nit_section.o \
+ dvb/rst_section.o \
+ dvb/sdt_section.o \
+ dvb/sit_section.o \
+ dvb/st_section.o \
+ dvb/tdt_section.o \
+ dvb/tot_section.o \
+ dvb/tva_container_section.o \
+ dvb/types.o
+
+sub-install += dvb
+
+else
+
+includes = ac3_descriptor.h \
+ adaptation_field_data_descriptor.h \
+ ait_application_descriptor.h \
+ ait_application_icons_descriptor.h \
+ ait_application_name_descriptor.h \
+ ait_external_application_authorisation_descriptor.h \
+ ancillary_data_descriptor.h \
+ announcement_support_descriptor.h \
+ application_signalling_descriptor.h \
+ bat_section.h \
+ bouquet_name_descriptor.h \
+ ca_identifier_descriptor.h \
+ cable_delivery_descriptor.h \
+ cell_frequency_link_descriptor.h \
+ cell_list_descriptor.h \
+ component_descriptor.h \
+ content_descriptor.h \
+ content_identifier_descriptor.h \
+ country_availability_descriptor.h \
+ data_broadcast_descriptor.h \
+ data_broadcast_id_descriptor.h \
+ default_authority_descriptor.h \
+ descriptor.h \
+ dit_section.h \
+ dsng_descriptor.h \
+ eit_section.h \
+ extended_event_descriptor.h \
+ frequency_list_descriptor.h \
+ int_section.h \
+ ip_mac_platform_name_descriptor.h \
+ ip_mac_platform_provider_name_descriptor.h \
+ ip_mac_stream_location_descriptor.h \
+ linkage_descriptor.h \
+ local_time_offset_descriptor.h \
+ mhp_data_broadcast_id_descriptor.h \
+ mosaic_descriptor.h \
+ multilingual_bouquet_name_descriptor.h \
+ multilingual_component_descriptor.h \
+ multilingual_network_name_descriptor.h \
+ multilingual_service_name_descriptor.h \
+ network_name_descriptor.h \
+ nit_section.h \
+ nvod_reference_descriptor.h \
+ parental_rating_descriptor.h \
+ partial_transport_stream_descriptor.h \
+ pdc_descriptor.h \
+ private_data_specifier_descriptor.h \
+ related_content_descriptor.h \
+ rnt_rar_over_dvb_stream_descriptor.h \
+ rnt_rar_over_ip_descriptor.h \
+ rnt_rnt_scan_descriptor.h \
+ rst_section.h \
+ s2_satellite_delivery_descriptor.h \
+ satellite_delivery_descriptor.h \
+ scrambling_descriptor.h \
+ sdt_section.h \
+ section.h \
+ service_availability_descriptor.h \
+ service_descriptor.h \
+ service_identifier_descriptor.h \
+ service_list_descriptor.h \
+ service_move_descriptor.h \
+ short_event_descriptor.h \
+ short_smoothing_buffer_descriptor.h \
+ sit_section.h \
+ st_section.h \
+ stream_identifier_descriptor.h \
+ stuffing_descriptor.h \
+ subtitling_descriptor.h \
+ target_ip_address_descriptor.h \
+ target_ipv6_address_descriptor.h \
+ target_ip_slash_descriptor.h \
+ target_ip_source_slash_descriptor.h \
+ target_ipv6_slash_descriptor.h \
+ target_ipv6_source_slash_descriptor.h \
+ tdt_section.h \
+ telephone_descriptor.h \
+ teletext_descriptor.h \
+ terrestrial_delivery_descriptor.h \
+ time_shifted_event_descriptor.h \
+ time_shifted_service_descriptor.h \
+ tot_section.h \
+ transport_stream_descriptor.h \
+ tva_container_section.h \
+ tva_id_descriptor.h \
+ types.h \
+ vbi_data_descriptor.h \
+ vbi_teletext_descriptor.h
+
+include ../../../Make.rules
+
+lib_name = libucsi/dvb
+
+endif
diff --git a/lib/libucsi/dvb/ac3_descriptor.h b/lib/libucsi/dvb/ac3_descriptor.h
new file mode 100644
index 0000000..0a2a5cd
--- /dev/null
+++ b/lib/libucsi/dvb/ac3_descriptor.h
@@ -0,0 +1,88 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_AC3_DESCRIPTOR
+#define _UCSI_DVB_AC3_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_ac3_descriptor structure.
+ */
+struct dvb_ac3_descriptor {
+ struct descriptor d;
+
+ EBIT5(uint8_t ac3_type_flag : 1; ,
+ uint8_t bsid_flag : 1; ,
+ uint8_t mainid_flag : 1; ,
+ uint8_t asvc_flag : 1; ,
+ uint8_t reserved : 4; );
+ /* uint8_t additional_info[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ac3_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_ac3_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ac3_descriptor*
+ dvb_ac3_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_ac3_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_ac3_descriptor*) d;
+}
+
+/**
+ * Retrieve pointer to additional_info field of a dvb_ac3_descriptor.
+ *
+ * @param d dvb_ac3_descriptor pointer.
+ * @return Pointer to additional_info field.
+ */
+static inline uint8_t *dvb_ac3_descriptor_additional_info(struct dvb_ac3_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_ac3_descriptor);
+}
+
+/**
+ * Determine length of additional_info field of a dvb_ac3_descriptor.
+ *
+ * @param d dvb_ac3_descriptor pointer.
+ * @return Length of field in bytes.
+ */
+static inline int dvb_ac3_descriptor_additional_info_length(struct dvb_ac3_descriptor *d)
+{
+ return d->d.len - 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/adaptation_field_data_descriptor.h b/lib/libucsi/dvb/adaptation_field_data_descriptor.h
new file mode 100644
index 0000000..b207054
--- /dev/null
+++ b/lib/libucsi/dvb/adaptation_field_data_descriptor.h
@@ -0,0 +1,62 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_ADAPTATION_FIELD_DATA_DESCRIPTOR
+#define _UCSI_DVB_ADAPTATION_FIELD_DATA_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_adaptation_field_data_descriptor structure.
+ */
+struct dvb_adaptation_field_data_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 7; ,
+ uint8_t announcement_switching_data : 1; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_adaptation_field_data_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to dvb_adaptation_field_data_descriptor, or NULL on error.
+ */
+static inline struct dvb_adaptation_field_data_descriptor*
+ dvb_adaptation_field_data_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_adaptation_field_data_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_adaptation_field_data_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ait_application_descriptor.h b/lib/libucsi/dvb/ait_application_descriptor.h
new file mode 100644
index 0000000..95fb7e3
--- /dev/null
+++ b/lib/libucsi/dvb/ait_application_descriptor.h
@@ -0,0 +1,204 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_AIT_APPLICATION_DESCRIPTOR
+#define _UCSI_DVB_AIT_APPLICATION_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for the visibility field.
+ */
+enum {
+ AVB_AIT_APPLICATION_VISIBILITY_HIDDEN = 0x00,
+ AVB_AIT_APPLICATION_VISIBILITY_APPSONLY = 0x01,
+ AVB_AIT_APPLICATION_VISIBILITY_VISIBLE = 0x03,
+};
+
+/**
+ * dvb_ait_application_descriptor structure.
+ */
+struct dvb_ait_application_descriptor {
+ struct descriptor d;
+
+ uint8_t application_profiles_length;
+ /* struct dvb_ait_application_profile profiles [] */
+ /* struct dvb_ait_application_descriptor_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * An entry in the profiles field of a dvb_ait_application_descriptor.
+ */
+struct dvb_ait_application_profile {
+ uint16_t application_profile;
+ uint8_t version_major;
+ uint8_t version_minor;
+ uint8_t version_micro;
+} __ucsi_packed;
+
+/**
+ * Second part of a dvb_ait_application_descriptor structure.
+ */
+struct dvb_ait_application_descriptor_part2 {
+ EBIT3(uint8_t service_bound_flag : 1; ,
+ uint8_t visibility : 2; ,
+ uint8_t reserved : 5; );
+ uint8_t application_priority;
+ /* uint8_t transport_protocol_label[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ait_application_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ait_application_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ait_application_descriptor*
+ dvb_ait_application_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint32_t pos2 = 0;
+ uint32_t len = d->len + 2;
+ uint8_t* buf = (uint8_t*) d;
+ struct dvb_ait_application_descriptor *ret =
+ (struct dvb_ait_application_descriptor*) d;
+
+ if (len < sizeof(struct dvb_ait_application_descriptor))
+ return NULL;
+
+ if (len < (sizeof(struct dvb_ait_application_descriptor) + ret->application_profiles_length))
+ return NULL;
+
+ if (ret->application_profiles_length % sizeof(struct dvb_ait_application_profile))
+ return NULL;
+
+ pos += sizeof(struct dvb_ait_application_descriptor);
+ pos2 = 0;
+ while(pos2 < ret->application_profiles_length) {
+ bswap16(buf + pos + pos2);
+ pos2 += sizeof(struct dvb_ait_application_descriptor);
+ }
+ pos += pos2;
+
+ if (len < (pos + sizeof(struct dvb_ait_application_descriptor_part2)))
+ return NULL;
+
+ return ret;
+}
+
+/**
+ * Iterator for the profiles field of a dvb_ait_application_descriptor.
+ *
+ * @param d dvb_ait_application_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ait_application_profile.
+ */
+#define dvb_ait_application_descriptor_profiles_for_each(d, pos) \
+ for ((pos) = dvb_ait_application_descriptor_profiles_first(d); \
+ (pos); \
+ (pos) = dvb_ait_application_descriptor_profiles_next(d, pos))
+
+/**
+ * Accessor for the part2 field of a dvb_ait_application_descriptor.
+ *
+ * @param d dvb_ait_application_descriptor pointer.
+ * @return dvb_ait_application_descriptor_part2 pointer.
+ */
+static inline struct dvb_ait_application_descriptor_part2*
+ dvb_ait_application_descriptor_part2(struct dvb_ait_application_descriptor* d)
+{
+ return (struct dvb_ait_application_descriptor_part2*)
+ ((uint8_t*) d +
+ sizeof(struct dvb_ait_application_descriptor) +
+ d->application_profiles_length);
+}
+
+/**
+ * Accessor for the transport_protocol_label field of a dvb_ait_application_descriptor_part2.
+ *
+ * @param d dvb_ait_application_descriptor_part2 pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_ait_application_descriptor_part2_transport_protocol_label(struct dvb_ait_application_descriptor_part2* d)
+{
+ return (uint8_t*) d +
+ sizeof(struct dvb_ait_application_descriptor_part2);
+}
+
+/**
+ * Calculate the number of bytes in the transport_protocol_label field of a dvb_ait_application_descriptor_part2.
+ *
+ * @param d dvb_ait_application_descriptor pointer.
+ * @param part2 dvb_ait_application_descriptor_part2 pointer.
+ * @return Number of bytes.
+ */
+static inline int
+ dvb_ait_application_descriptor_part2_transport_protocol_label_length(struct dvb_ait_application_descriptor *d,
+ struct dvb_ait_application_descriptor_part2* part2)
+{
+ uint8_t *ptr = (uint8_t*) part2 + sizeof(struct dvb_ait_application_descriptor_part2);
+ uint8_t *end = (uint8_t*) d + d->d.len + 2;
+
+ return (int) (end - ptr);
+}
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ait_application_profile*
+ dvb_ait_application_descriptor_profiles_first(struct dvb_ait_application_descriptor *d)
+{
+ if (d->application_profiles_length == 0)
+ return NULL;
+
+ return (struct dvb_ait_application_profile *)
+ ((uint8_t*) d + sizeof(struct dvb_ait_application_descriptor));
+}
+
+static inline struct dvb_ait_application_profile*
+ dvb_ait_application_descriptor_profiles_next(struct dvb_ait_application_descriptor *d,
+ struct dvb_ait_application_profile *pos)
+{
+ uint8_t *end = (uint8_t*) d +
+ sizeof(struct dvb_ait_application_descriptor) +
+ d->application_profiles_length;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ait_application_profile);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ait_application_profile *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ait_application_icons_descriptor.h b/lib/libucsi/dvb/ait_application_icons_descriptor.h
new file mode 100644
index 0000000..431cd6c
--- /dev/null
+++ b/lib/libucsi/dvb/ait_application_icons_descriptor.h
@@ -0,0 +1,157 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_AIT_APPLICATION_ICONS_DESCRIPTOR
+#define _UCSI_DVB_AIT_APPLICATION_ICONS_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * Possible values for the icon_flags field.
+ */
+enum {
+ AIT_APPLICATION_ICON_FLAG_32_32 = 0x001,
+ AIT_APPLICATION_ICON_FLAG_32_32_43 = 0x002,
+ AIT_APPLICATION_ICON_FLAG_24_32_169 = 0x004,
+
+ AIT_APPLICATION_ICON_FLAG_64_64 = 0x008,
+ AIT_APPLICATION_ICON_FLAG_64_64_43 = 0x010,
+ AIT_APPLICATION_ICON_FLAG_48_64_169 = 0x020,
+
+ AIT_APPLICATION_ICON_FLAG_128_128 = 0x040,
+ AIT_APPLICATION_ICON_FLAG_128_128_43 = 0x080,
+ AIT_APPLICATION_ICON_FLAG_96_128_169 = 0x100,
+};
+
+/**
+ * dvb_ait_application_icons_descriptor structure.
+ */
+struct dvb_ait_application_icons_descriptor {
+ struct descriptor d;
+
+ uint8_t icon_locator_length;
+ /* uint8_t icon_locator[] */
+ /* struct dvb_ait_application_icons_descriptor_part2 */
+} __ucsi_packed;
+
+/**
+ * Second part of a dvb_ait_application_icons_descriptor.
+ */
+struct dvb_ait_application_icons_descriptor_part2 {
+ uint16_t icon_flags;
+ /* uint8_t reserved[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ait_application_icons_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ait_application_icons_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ait_application_icons_descriptor*
+ dvb_ait_application_icons_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d;
+ uint32_t pos = 0;
+ uint32_t len = d->len + 2;
+ struct dvb_ait_application_icons_descriptor *ret =
+ (struct dvb_ait_application_icons_descriptor *) d;
+
+ if (len < sizeof(struct dvb_ait_application_icons_descriptor))
+ return NULL;
+ if (len < (sizeof(struct dvb_ait_application_icons_descriptor) + ret->icon_locator_length))
+ return NULL;
+
+ pos += sizeof(struct dvb_ait_application_icons_descriptor) + ret->icon_locator_length;
+
+ if ((len - pos) < sizeof(struct dvb_ait_application_icons_descriptor_part2))
+ return NULL;
+ bswap16(buf + pos);
+
+ return ret;
+}
+/**
+ * Accessor for the icon_locator field of a dvb_ait_application_icons_descriptor.
+ *
+ * @param e dvb_ait_application_icons_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_ait_application_icons_descriptor_icon_locator(struct dvb_ait_application_icons_descriptor *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_ait_application_icons_descriptor);
+}
+
+/**
+ * Accessor for the part2 field of a dvb_ait_application_icons_descriptor.
+ *
+ * @param e dvb_ait_application_icons_descriptor Pointer.
+ * @return dvb_ait_application_icons_descriptor_part2 pointer.
+ */
+static inline struct dvb_ait_application_icons_descriptor_part2 *
+ dvb_ait_application_icons_descriptor_part2(struct dvb_ait_application_icons_descriptor *e)
+{
+ return (struct dvb_ait_application_icons_descriptor_part2 *)
+ ((uint8_t *) e + sizeof(struct dvb_ait_application_icons_descriptor) +
+ e->icon_locator_length);
+}
+
+/**
+ * Accessor for the reserved field of a dvb_ait_application_icons_descriptor_part2.
+ *
+ * @param e dvb_ait_application_icons_part2 pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_ait_application_icons_descriptor_part2_reserved(struct dvb_ait_application_icons_descriptor_part2 *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_ait_application_icons_descriptor_part2);
+}
+
+/**
+ * Calculate the number of bytes in the reserved field of a dvb_ait_application_icons_descriptor_part2.
+ *
+ * @param d dvb_ait_application_icons_descriptorpointer.
+ * @param part2 dvb_ait_application_icons_descriptor_part2 pointer.
+ * @return Number of bytes.
+ */
+static inline int
+ dvb_ait_application_icons_descriptor_part2_reserved_length(struct dvb_ait_application_icons_descriptor *d,
+ struct dvb_ait_application_icons_descriptor_part2* part2)
+{
+ uint8_t *ptr = (uint8_t*) part2 + sizeof(struct dvb_ait_application_icons_descriptor_part2);
+ uint8_t *end = (uint8_t*) d + d->d.len + 2;
+
+ return (int) (end - ptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ait_application_name_descriptor.h b/lib/libucsi/dvb/ait_application_name_descriptor.h
new file mode 100644
index 0000000..a4b719e
--- /dev/null
+++ b/lib/libucsi/dvb/ait_application_name_descriptor.h
@@ -0,0 +1,145 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_AIT_APPLICATION_NAME_DESCRIPTOR
+#define _UCSI_DVB_AIT_APPLICATION_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_ait_application_name_descriptor structure.
+ */
+struct dvb_ait_application_name_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_ait_application_name names[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the names field of a dvb_ait_application_name_descriptor.
+ */
+struct dvb_ait_application_name {
+ iso639lang_t language_code;
+ uint8_t application_name_length;
+ /* uint8_t name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ait_application_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ait_application_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ait_application_name_descriptor*
+ dvb_ait_application_name_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_ait_application_name *e =
+ (struct dvb_ait_application_name*) (buf + pos);
+
+ pos += sizeof(struct dvb_ait_application_name);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e->application_name_length;
+
+ if (pos > len)
+ return NULL;
+ }
+
+ return (struct dvb_ait_application_name_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the names field of a dvb_ait_application_name_descriptor.
+ *
+ * @param d dvb_ait_application_name_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ait_application_name.
+ */
+#define dvb_ait_application_name_descriptor_names_for_each(d, pos) \
+ for ((pos) = dvb_ait_application_name_descriptor_names_first(d); \
+ (pos); \
+ (pos) = dvb_ait_application_name_descriptor_names_next(d, pos))
+
+/**
+ * Accessor for the name field of a dvb_ait_application_name.
+ *
+ * @param e dvb_ait_application_name pointer.
+ * @return Pointer to the name field.
+ */
+static inline uint8_t *
+ dvb_ait_application_name_name(struct dvb_ait_application_name *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_ait_application_name);
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ait_application_name*
+ dvb_ait_application_name_descriptor_names_first(struct dvb_ait_application_name_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_ait_application_name *)
+ ((uint8_t*) d + sizeof(struct dvb_ait_application_name_descriptor));
+}
+
+static inline struct dvb_ait_application_name*
+ dvb_ait_application_name_descriptor_names_next(struct dvb_ait_application_name_descriptor *d,
+ struct dvb_ait_application_name *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_ait_application_name) +
+ pos->application_name_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ait_application_name *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ait_external_application_authorisation_descriptor.h b/lib/libucsi/dvb/ait_external_application_authorisation_descriptor.h
new file mode 100644
index 0000000..34f584a
--- /dev/null
+++ b/lib/libucsi/dvb/ait_external_application_authorisation_descriptor.h
@@ -0,0 +1,125 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_AIT_EXTERNAL_APPLICATION_AUTHORISATION_DESCRIPTOR
+#define _UCSI_DVB_AIT_EXTERNAL_APPLICATION_AUTHORISATION_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_ait_external_application_authorisation_descriptor structure.
+ */
+struct dvb_ait_external_application_authorisation_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_ait_external_application_authorisation auths[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the auths field of a dvb_ait_external_application_authorisation_descriptor.
+ */
+struct dvb_ait_external_application_authorisation {
+ uint32_t organization_id;
+ uint16_t application_id;
+ uint8_t application_priority;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ait_external_application_authorisation_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ait_external_application_authorisation_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ait_external_application_authorisation_descriptor*
+ dvb_ait_external_application_authorisation_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_ait_external_application_authorisation))
+ return NULL;
+
+ while(pos < len) {
+ bswap32(buf + pos);
+ bswap32(buf + pos + 4);
+ pos += sizeof(struct dvb_ait_external_application_authorisation);
+ }
+
+ return (struct dvb_ait_external_application_authorisation_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the auths field of a dvb_ait_external_application_authorisation_descriptor.
+ *
+ * @param d dvb_ait_external_application_authorisation_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ait_external_application_authorisation.
+ */
+#define dvb_ait_external_application_authorisation_descriptor_auths_for_each(d, pos) \
+ for ((pos) = dvb_ait_external_application_authorisation_descriptor_auths_first(d); \
+ (pos); \
+ (pos) = dvb_ait_external_application_authorisation_descriptor_auths_next(d, pos))
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ait_external_application_authorisation*
+ dvb_ait_external_application_authorisation_descriptor_auths_first(struct dvb_ait_external_application_authorisation_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_ait_external_application_authorisation *)
+ ((uint8_t*) d + sizeof(struct dvb_ait_external_application_authorisation_descriptor));
+}
+
+static inline struct dvb_ait_external_application_authorisation*
+ dvb_ait_external_application_authorisation_descriptor_auths_next(struct dvb_ait_external_application_authorisation_descriptor *d,
+ struct dvb_ait_external_application_authorisation *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_ait_external_application_authorisation);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ait_external_application_authorisation *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ancillary_data_descriptor.h b/lib/libucsi/dvb/ancillary_data_descriptor.h
new file mode 100644
index 0000000..04b2f59
--- /dev/null
+++ b/lib/libucsi/dvb/ancillary_data_descriptor.h
@@ -0,0 +1,67 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_ANCILLARY_DATA_DESCRIPTOR
+#define _UCSI_DVB_ANCILLARY_DATA_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_ancillary_data_descriptor structure.
+ */
+struct dvb_ancillary_data_descriptor {
+ struct descriptor d;
+ EBIT8(uint8_t reserved : 1; ,
+ uint8_t rds_via_udcp : 1; ,
+ uint8_t mpeg4_ancillary_data : 1; ,
+ uint8_t scale_factor_error_check : 1; ,
+ uint8_t dab_ancillary_data : 1; ,
+ uint8_t announcement_switching_data : 1; ,
+ uint8_t extended_ancillary_data : 1; ,
+ uint8_t dvd_video_ancillary_data : 1; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ancillary_data_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ancillary_data_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ancillary_data_descriptor*
+ dvb_ancillary_data_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_ancillary_data_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_ancillary_data_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/announcement_support_descriptor.h b/lib/libucsi/dvb/announcement_support_descriptor.h
new file mode 100644
index 0000000..9eb20c4
--- /dev/null
+++ b/lib/libucsi/dvb/announcement_support_descriptor.h
@@ -0,0 +1,219 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_ANNOUNCEMENT_SUPPORT_DESCRIPTOR
+#define _UCSI_DVB_ANNOUNCEMENT_SUPPORT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for announcement_support_indicator.
+ */
+enum {
+ DVB_ANNOUNCEMENT_SUPPORT_EMERGENCY = 0x01,
+ DVB_ANNOUNCEMENT_SUPPORT_ROAD_TRAFFIC_FLASH = 0x02,
+ DVB_ANNOUNCEMENT_SUPPORT_PUBLIC_TRANSPORT_FLASH = 0x04,
+ DVB_ANNOUNCEMENT_SUPPORT_WARNING_MESSAGE = 0x08,
+ DVB_ANNOUNCEMENT_SUPPORT_NEWS_FLASH = 0x10,
+ DVB_ANNOUNCEMENT_SUPPORT_WEATHER_FLASH = 0x20,
+ DVB_ANNOUNCEMENT_SUPPORT_EVENT_ANNOUNCEMENT = 0x40,
+ DVB_ANNOUNCEMENT_SUPPORT_PERSONAL_CALL = 0x80,
+};
+
+/**
+ * Possible values for announcement_type.
+ */
+enum {
+ DVB_ANNOUNCEMENT_TYPE_EMERGENCY = 0x00,
+ DVB_ANNOUNCEMENT_TYPE_ROAD_TRAFFIC_FLASH = 0x01,
+ DVB_ANNOUNCEMENT_TYPE_PUBLIC_TRANSPORT_FLASH = 0x02,
+ DVB_ANNOUNCEMENT_TYPE_WARNING_MESSAGE = 0x03,
+ DVB_ANNOUNCEMENT_TYPE_NEWS_FLASH = 0x04,
+ DVB_ANNOUNCEMENT_TYPE_WEATHER_FLASH = 0x05,
+ DVB_ANNOUNCEMENT_TYPE_EVENT_ANNOUNCEMENT = 0x06,
+ DVB_ANNOUNCEMENT_TYPE_PERSONAL_CALL = 0x07,
+};
+
+/**
+ * Possible values for reference_type.
+ */
+enum {
+ DVB_REFERENCE_TYPE_AUDIO = 0x00,
+ DVB_REFERENCE_TYPE_OTHER_AUDIO = 0x01,
+ DVB_REFERENCE_TYPE_OTHER_SERVICE = 0x02,
+ DVB_REFERENCE_TYPE_OTHER_TS = 0x03,
+};
+
+/**
+ * dvb_announcement_support_descriptor structure.
+ */
+struct dvb_announcement_support_descriptor {
+ struct descriptor d;
+ uint16_t announcement_support_indicator;
+ /* struct dvb_announcement_support_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a dvb_announcement_support_descriptor.
+ */
+struct dvb_announcement_support_entry {
+ EBIT3(uint8_t announcement_type : 4; ,
+ uint8_t reserved : 1; ,
+ uint8_t reference_type : 3; );
+ /* Only if reference_type == 1, 2 or 3:
+ * struct dvb_announcement_support_reference reference */
+} __ucsi_packed;
+
+/**
+ * The optional reference field only present in a dvb_announcement_support_descriptor if
+ * its reference_type field is 1,2 or 3.
+ */
+struct dvb_announcement_support_reference {
+ uint16_t original_network_id;
+ uint16_t transport_stream_id;
+ uint16_t service_id;
+ uint8_t component_tag;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_announcement_support_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_announcement_support_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_announcement_support_descriptor*
+ dvb_announcement_support_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ if (len < (sizeof(struct dvb_announcement_support_descriptor) - 2))
+ return NULL;
+
+ bswap16(buf+pos);
+
+ pos += 2;
+
+ while(pos < len) {
+ struct dvb_announcement_support_entry *e =
+ (struct dvb_announcement_support_entry*) (buf+pos);
+
+ pos += sizeof(struct dvb_announcement_support_entry);
+
+ if (pos > len)
+ return NULL;
+
+ if ((e->reference_type == 1) ||
+ (e->reference_type == 2) ||
+ (e->reference_type == 3)) {
+ if ((pos + sizeof(struct dvb_announcement_support_reference)) > len)
+ return NULL;
+
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap16(buf+pos+4);
+
+ pos += sizeof(struct dvb_announcement_support_reference);
+ }
+ }
+
+ return (struct dvb_announcement_support_descriptor*) d;
+}
+
+/**
+ * Iterator for the entries field of a dvb_announcement_support_descriptor.
+ *
+ * @param d dvb_announcement_support_descriptor pointer.
+ * @param pod Variable holding a pointer to the current dvb_announcement_support_entry.
+ */
+#define dvb_announcement_support_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_announcement_support_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_announcement_support_descriptor_entries_next(d, pos))
+
+/**
+ * Accessor for the reference field of a dvb_announcement_support_entry if present.
+ *
+ * @param entry dvb_announcement_support_entry pointer.
+ * @return dvb_announcement_support_reference pointer, or NULL on error.
+ */
+static inline struct dvb_announcement_support_reference*
+ dvb_announcement_support_entry_reference(struct dvb_announcement_support_entry* entry)
+{
+ if ((entry->reference_type != 0x01) &&
+ (entry->reference_type != 0x02) &&
+ (entry->reference_type != 0x03))
+ return NULL;
+
+ return (struct dvb_announcement_support_reference*)
+ ((uint8_t*) entry + sizeof(struct dvb_announcement_support_entry));
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_announcement_support_entry*
+ dvb_announcement_support_descriptor_entries_first(struct dvb_announcement_support_descriptor *d)
+{
+ if (d->d.len == 2)
+ return NULL;
+
+ return (struct dvb_announcement_support_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_announcement_support_descriptor));
+}
+
+static inline struct dvb_announcement_support_entry*
+ dvb_announcement_support_descriptor_entries_next(struct dvb_announcement_support_descriptor *d,
+ struct dvb_announcement_support_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t* next = (uint8_t*) pos + sizeof(struct dvb_announcement_support_entry);
+ struct dvb_announcement_support_reference* reference =
+ dvb_announcement_support_entry_reference(pos);
+
+ if (reference)
+ next += sizeof(struct dvb_announcement_support_reference);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_announcement_support_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/application_signalling_descriptor.h b/lib/libucsi/dvb/application_signalling_descriptor.h
new file mode 100644
index 0000000..78211cf
--- /dev/null
+++ b/lib/libucsi/dvb/application_signalling_descriptor.h
@@ -0,0 +1,124 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_APPLICATION_SIGNALLING_DESCRIPTOR
+#define _UCSI_DVB_APPLICATION_SIGNALLING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_application_signalling_descriptor structure.
+ */
+struct dvb_application_signalling_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_application_signalling_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a dvb_application_signalling_descriptor.
+ */
+struct dvb_application_signalling_entry {
+ uint16_t application_type;
+ EBIT2(uint8_t reserved : 3; ,
+ uint8_t AIT_version_number : 5; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_application_signalling_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_application_signalling_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_application_signalling_descriptor*
+ dvb_application_signalling_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+ uint8_t* buf = (uint8_t*) d + 2;
+
+ pos += sizeof(struct dvb_application_signalling_descriptor) - 2;
+ if (len % sizeof(struct dvb_application_signalling_entry))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ pos+=3;
+ }
+
+ return (struct dvb_application_signalling_descriptor*) d;
+}
+
+/**
+ * Iterator for the entries field of a dvb_application_signalling_descriptor.
+ *
+ * @param d dvb_application_signalling_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_application_signalling_entry.
+ */
+#define dvb_application_signalling_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_application_signalling_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_application_signalling_descriptor_entries_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_application_signalling_entry*
+ dvb_application_signalling_descriptor_entries_first(struct dvb_application_signalling_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_application_signalling_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_application_signalling_descriptor));
+}
+
+static inline struct dvb_application_signalling_entry*
+ dvb_application_signalling_descriptor_entries_next(struct dvb_application_signalling_descriptor *d,
+ struct dvb_application_signalling_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_application_signalling_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_application_signalling_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/bat_section.c b/lib/libucsi/dvb/bat_section.c
new file mode 100644
index 0000000..99e5cf6
--- /dev/null
+++ b/lib/libucsi/dvb/bat_section.c
@@ -0,0 +1,77 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/bat_section.h>
+
+struct dvb_bat_section * dvb_bat_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+ struct dvb_bat_section * ret = (struct dvb_bat_section *) ext;
+
+ if (len < sizeof(struct dvb_bat_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+
+ if ((pos + ret->bouquet_descriptors_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, ret->bouquet_descriptors_length))
+ return NULL;
+ pos += ret->bouquet_descriptors_length;
+
+ if ((pos + sizeof(struct dvb_bat_section_part2)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += sizeof(struct dvb_bat_section_part2);
+
+ while (pos < len) {
+ struct dvb_bat_transport * transport =
+ (struct dvb_bat_transport *) (buf + pos);
+
+ if ((pos + sizeof(struct dvb_bat_transport)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 2);
+ bswap16(buf + pos + 4);
+
+ pos += sizeof(struct dvb_bat_transport);
+
+ if ((pos + transport->transport_descriptors_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos,
+ transport->transport_descriptors_length))
+ return NULL;
+
+ pos += transport->transport_descriptors_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/bat_section.h b/lib/libucsi/dvb/bat_section.h
new file mode 100644
index 0000000..94ed8a4
--- /dev/null
+++ b/lib/libucsi/dvb/bat_section.h
@@ -0,0 +1,211 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_BAT_SECTION_H
+#define _UCSI_DVB_BAT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_bat_section structure.
+ */
+struct dvb_bat_section {
+ struct section_ext head;
+
+ EBIT2(uint16_t reserved_1 : 4; ,
+ uint16_t bouquet_descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+ /* struct dvb_bat_section_part2 part2 */
+};
+
+/**
+ * Second part of a dvb_bat_section, following the variable length descriptors field.
+ */
+struct dvb_bat_section_part2 {
+ EBIT2(uint16_t reserved_2 : 4; ,
+ uint16_t transport_stream_loop_length :12; );
+ /* struct dvb_bat_transport transports[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the transports field of a dvb_bat_section_part2.
+ */
+struct dvb_bat_transport {
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ EBIT2(uint16_t reserved : 4; ,
+ uint16_t transport_descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+};
+
+/**
+ * Process a dvb_bat_section.
+ *
+ * @param section Generic section pointer.
+ * @return dvb_bat_section pointer, or NULL on error.
+ */
+struct dvb_bat_section *dvb_bat_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the bouquet_id field of a BAT.
+ *
+ * @param bat BAT pointer.
+ * @return The bouquet_id.
+ */
+static inline uint16_t dvb_bat_section_bouquet_id(struct dvb_bat_section *bat)
+{
+ return bat->head.table_id_ext;
+}
+
+/**
+ * Iterator for the descriptors field in a dvb_bat_section.
+ *
+ * @param bat dvb_bat_section pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define dvb_bat_section_descriptors_for_each(bat, pos) \
+ for ((pos) = dvb_bat_section_descriptors_first(bat); \
+ (pos); \
+ (pos) = dvb_bat_section_descriptors_next(bat, pos))
+
+/**
+ * Accessor for the second part of a dvb_bat_section.
+ *
+ * @param bat dvb_bat_section pointer.
+ * @return dvb_bat_section_part2 pointer.
+ */
+static inline struct dvb_bat_section_part2 *
+ dvb_bat_section_part2(struct dvb_bat_section *bat)
+{
+ return (struct dvb_bat_section_part2 *)
+ ((uint8_t*) bat +
+ sizeof(struct dvb_bat_section) +
+ bat->bouquet_descriptors_length);
+
+}
+
+/**
+ * Iterator for the transports field of a dvb_bat_section_part2.
+ *
+ * @param part2 dvb_bat_section_part2 pointer.
+ * @param pos Variable containing a pointer to the current dvb_bat_transport.
+ */
+#define dvb_bat_section_transports_for_each(part2, pos) \
+ for ((pos) = dvb_bat_section_transports_first(part2); \
+ (pos); \
+ (pos) = dvb_bat_section_transports_next(part2, pos))
+
+/**
+ * Iterator for the descriptors field of a dvb_bat_transport.
+ *
+ * @param transport dvb_bat_transport pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define dvb_bat_transport_descriptors_for_each(transport, pos) \
+ for ((pos) = dvb_bat_transport_descriptors_first(transport); \
+ (pos); \
+ (pos) = dvb_bat_transport_descriptors_next(transport, pos))
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ dvb_bat_section_descriptors_first(struct dvb_bat_section *bat)
+{
+ if (bat->bouquet_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) bat + sizeof(struct dvb_bat_section));
+}
+
+static inline struct descriptor *
+ dvb_bat_section_descriptors_next(struct dvb_bat_section *bat,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) bat + sizeof(struct dvb_bat_section),
+ bat->bouquet_descriptors_length,
+ pos);
+}
+
+static inline struct dvb_bat_transport *
+ dvb_bat_section_transports_first(struct dvb_bat_section_part2 *part2)
+{
+ if (part2->transport_stream_loop_length == 0)
+ return NULL;
+
+ return (struct dvb_bat_transport *)
+ ((uint8_t *) part2 + sizeof(struct dvb_bat_section_part2));
+}
+
+static inline struct dvb_bat_transport *
+ dvb_bat_section_transports_next(struct dvb_bat_section_part2 *part2,
+ struct dvb_bat_transport *pos)
+{
+ uint8_t *end = (uint8_t*) part2 + sizeof(struct dvb_bat_section_part2) +
+ part2->transport_stream_loop_length;
+ uint8_t *next = (uint8_t*) pos + sizeof(struct dvb_bat_transport) +
+ pos->transport_descriptors_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_bat_transport *) next;
+}
+
+static inline struct descriptor *
+ dvb_bat_transport_descriptors_first(struct dvb_bat_transport *t)
+{
+ if (t->transport_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t*)t + sizeof(struct dvb_bat_transport));
+}
+
+static inline struct descriptor *
+ dvb_bat_transport_descriptors_next(struct dvb_bat_transport *t,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) t + sizeof(struct dvb_bat_transport),
+ t->transport_descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/bouquet_name_descriptor.h b/lib/libucsi/dvb/bouquet_name_descriptor.h
new file mode 100644
index 0000000..a298849
--- /dev/null
+++ b/lib/libucsi/dvb/bouquet_name_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_BOUQUET_NAME_DESCRIPTOR
+#define _UCSI_DVB_BOUQUET_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_bouquet_name_descriptor structure.
+ */
+struct dvb_bouquet_name_descriptor {
+ struct descriptor d;
+
+ /* uint8_t name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_bouquet_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_bouquet_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_bouquet_name_descriptor*
+ dvb_bouquet_name_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_bouquet_name_descriptor*) d;
+}
+
+/**
+ * Accessor for the name field of a dvb_bouquet_name_descriptor.
+ *
+ * @param d dvb_bouquet_name_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_bouquet_name_descriptor_name(struct dvb_bouquet_name_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_bouquet_name_descriptor);
+}
+
+/**
+ * Determine the length of the name field of a dvb_bouquet_name_descriptor in bytes.
+ *
+ * @param d dvb_bouquet_name_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_bouquet_name_descriptor_name_length(struct dvb_bouquet_name_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ca_identifier_descriptor.h b/lib/libucsi/dvb/ca_identifier_descriptor.h
new file mode 100644
index 0000000..ac670a9
--- /dev/null
+++ b/lib/libucsi/dvb/ca_identifier_descriptor.h
@@ -0,0 +1,94 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_CA_IDENTIFIER_DESCRIPTOR
+#define _UCSI_DVB_CA_IDENTIFIER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_ca_identifier_descriptor structure.
+ */
+struct dvb_ca_identifier_descriptor {
+ struct descriptor d;
+
+ /* uint16_t ca_system_ids[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ca_identifier_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ca_identifier_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ca_identifier_descriptor*
+ dvb_ca_identifier_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+ uint8_t *buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+
+ if (len % 2)
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ pos+=2;
+ }
+
+ return (struct dvb_ca_identifier_descriptor*) d;
+}
+
+/**
+ * Accessor for the ca_system_ids field of a dvb_ca_identifier_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint16_t *
+ dvb_ca_identifier_descriptor_ca_system_ids(struct dvb_ca_identifier_descriptor *d)
+{
+ return (uint16_t *) ((uint8_t *) d + sizeof(struct dvb_ca_identifier_descriptor));
+}
+
+/**
+ * Calculate the number of entries in the ca_system_ids field of a dvb_ca_identifier_descriptor.
+ *
+ * @param d dvb_ca_identifier_descriptor pointer.
+ * @return Number of entries.
+ */
+static inline int
+ dvb_ca_identifier_descriptor_ca_system_ids_count(struct dvb_ca_identifier_descriptor *d)
+{
+ return d->d.len >> 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/cable_delivery_descriptor.h b/lib/libucsi/dvb/cable_delivery_descriptor.h
new file mode 100644
index 0000000..f0f92f3
--- /dev/null
+++ b/lib/libucsi/dvb/cable_delivery_descriptor.h
@@ -0,0 +1,70 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_CABLE_DELIVERY_DESCRIPTOR
+#define _UCSI_DVB_CABLE_DELIVERY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_cable_delivery_descriptor structure.
+ */
+struct dvb_cable_delivery_descriptor {
+ struct descriptor d;
+
+ uint32_t frequency; // BCD, units 100Hz
+ EBIT2(uint16_t reserved : 12; ,
+ uint16_t fec_outer : 4; );
+ uint8_t modulation;
+ EBIT2(uint32_t symbol_rate : 28; , // BCD, units 100Hz
+ uint32_t fec_inner : 4; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_cable_delivery_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_cable_delivery_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_cable_delivery_descriptor*
+ dvb_cable_delivery_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_cable_delivery_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+ bswap16((uint8_t*) d + 6);
+ bswap32((uint8_t*) d + 9);
+
+ return (struct dvb_cable_delivery_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/cell_frequency_link_descriptor.h b/lib/libucsi/dvb/cell_frequency_link_descriptor.h
new file mode 100644
index 0000000..63f7fd2
--- /dev/null
+++ b/lib/libucsi/dvb/cell_frequency_link_descriptor.h
@@ -0,0 +1,190 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_CELL_FREQUENCY_LINK_DESCRIPTOR
+#define _UCSI_DVB_CELL_FREQUENCY_LINK_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_cell_frequency_link_descriptor structure.
+ */
+struct dvb_cell_frequency_link_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_cell_frequency_link_cell cells[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the cells field of a dvb_cell_frequency_link_descriptor.
+ */
+struct dvb_cell_frequency_link_cell {
+ uint16_t cell_id;
+ uint32_t frequency;
+ uint8_t subcell_loop_info_length;
+ /* struct dvb_cell_frequency_link_subcell subcells[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the subcells field of a dvb_cell_frequency_link_cell.
+ */
+struct dvb_cell_frequency_link_cell_subcell {
+ uint8_t cell_id_extension;
+ uint32_t transposer_frequency;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_cell_frequency_link_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_cell_frequency_link_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_cell_frequency_link_descriptor*
+ dvb_cell_frequency_link_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint32_t pos2 = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_cell_frequency_link_cell *e =
+ (struct dvb_cell_frequency_link_cell*) (buf+pos);
+
+ if ((pos + sizeof(struct dvb_cell_frequency_link_cell)) > len)
+ return NULL;
+
+ bswap16(buf+pos);
+ bswap32(buf+pos+2);
+
+ pos += sizeof(struct dvb_cell_frequency_link_cell);
+
+ if ((pos + e->subcell_loop_info_length) > len)
+ return NULL;
+
+ if (e->subcell_loop_info_length % sizeof(struct dvb_cell_frequency_link_cell_subcell))
+ return NULL;
+
+ pos2 = 0;
+ while(pos2 < e->subcell_loop_info_length) {
+ bswap32(buf+pos+pos2+1);
+
+ pos2 += sizeof(struct dvb_cell_frequency_link_cell_subcell);
+ }
+
+ pos += e->subcell_loop_info_length;
+ }
+
+ return (struct dvb_cell_frequency_link_descriptor*) d;
+}
+
+/**
+ * Iterator for the cells field of a dvb_cell_frequency_link_descriptor.
+ *
+ * @param d dvb_cell_frequency_link_descriptor pointer.
+ * @param pos Variable holding a pointer to the current dvb_cell_frequency_link_cell.
+ */
+#define dvb_cell_frequency_link_descriptor_cells_for_each(d, pos) \
+ for ((pos) = dvb_cell_frequency_link_descriptor_cells_first(d); \
+ (pos); \
+ (pos) = dvb_cell_frequency_link_descriptor_cells_next(d, pos))
+
+/**
+ * Iterator for the subcells field of a dvb_cell_frequency_link_cell.
+ *
+ * @param cell dvb_cell_frequency_link_cell pointer.
+ * @param pos Variable holding a pointer to the current dvb_cell_frequency_link_cell_subcell.
+ */
+#define dvb_cell_frequency_link_cell_subcells_for_each(cell, pos) \
+ for ((pos) = dvb_cell_frequency_link_cell_subcells_first(cell); \
+ (pos); \
+ (pos) = dvb_cell_frequency_link_cell_subcells_next(cell, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_cell_frequency_link_cell*
+ dvb_cell_frequency_link_descriptor_cells_first(struct dvb_cell_frequency_link_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_cell_frequency_link_cell *)
+ ((uint8_t*) d + sizeof(struct dvb_cell_frequency_link_descriptor));
+}
+
+static inline struct dvb_cell_frequency_link_cell*
+ dvb_cell_frequency_link_descriptor_cells_next(struct dvb_cell_frequency_link_descriptor *d,
+ struct dvb_cell_frequency_link_cell *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_cell_frequency_link_cell) +
+ pos->subcell_loop_info_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_cell_frequency_link_cell *) next;
+}
+
+static inline struct dvb_cell_frequency_link_cell_subcell*
+ dvb_cell_frequency_link_cell_subcells_first(struct dvb_cell_frequency_link_cell *d)
+{
+ if (d->subcell_loop_info_length == 0)
+ return NULL;
+
+ return (struct dvb_cell_frequency_link_cell_subcell*)
+ ((uint8_t*) d + sizeof(struct dvb_cell_frequency_link_cell));
+}
+
+static inline struct dvb_cell_frequency_link_cell_subcell*
+ dvb_cell_frequency_link_cell_subcells_next(struct dvb_cell_frequency_link_cell *cell,
+ struct dvb_cell_frequency_link_cell_subcell *pos)
+{
+ uint8_t *end = (uint8_t*) cell + cell->subcell_loop_info_length;
+ uint8_t *next = (uint8_t*) pos +
+ sizeof(struct dvb_cell_frequency_link_cell_subcell);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_cell_frequency_link_cell_subcell *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/cell_list_descriptor.h b/lib/libucsi/dvb/cell_list_descriptor.h
new file mode 100644
index 0000000..ddbaf2c
--- /dev/null
+++ b/lib/libucsi/dvb/cell_list_descriptor.h
@@ -0,0 +1,201 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_CELL_LIST_DESCRIPTOR
+#define _UCSI_DVB_CELL_LIST_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_cell_list_descriptor structure.
+ */
+struct dvb_cell_list_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_cell_list_entry cells[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the cells field of a dvb_cell_list_descriptor.
+ */
+struct dvb_cell_list_entry {
+ uint16_t cell_id;
+ uint16_t cell_latitude;
+ uint16_t cell_longitude;
+ EBIT3(uint32_t cell_extend_of_latitude :12; ,
+ uint32_t cell_extend_of_longitude :12; ,
+ uint32_t subcell_info_loop_length : 8; );
+ /* struct dvb_subcell_list_entry subcells[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the subcells field of a dvb_cell_list_entry.
+ */
+struct dvb_subcell_list_entry {
+ uint8_t cell_id_extension;
+ uint16_t subcell_latitude;
+ uint16_t subcell_longitude;
+ EBIT2(uint32_t subcell_extend_of_latitude :12; ,
+ uint32_t subcell_extend_of_longitude :12; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_cell_list_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_cell_list_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_cell_list_descriptor*
+ dvb_cell_list_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint32_t pos2 = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_cell_list_entry *e =
+ (struct dvb_cell_list_entry*) (buf+pos);
+
+ if ((pos + sizeof(struct dvb_cell_list_entry)) > len)
+ return NULL;
+
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap16(buf+pos+4);
+ bswap32(buf+pos+6);
+
+ pos += sizeof(struct dvb_cell_list_entry);
+
+ if ((pos + e->subcell_info_loop_length) > len)
+ return NULL;
+
+ if (e->subcell_info_loop_length % sizeof(struct dvb_subcell_list_entry))
+ return NULL;
+
+ pos2 = 0;
+ while(pos2 < e->subcell_info_loop_length) {
+ bswap16(buf+pos+pos2+1);
+ bswap16(buf+pos+pos2+3);
+ bswap24(buf+pos+pos2+5);
+
+ pos2 += sizeof(struct dvb_subcell_list_entry);
+ }
+
+ pos += e->subcell_info_loop_length;
+ }
+
+ return (struct dvb_cell_list_descriptor*) d;
+}
+
+/**
+ * Iterator for the cells field of a dvb_cell_list_descriptor.
+ *
+ * @param d dvb_cell_list_descriptor pointer.
+ * @param pos Variable holding a pointer to the current dvb_cell_list_entry.
+ */
+#define dvb_cell_list_descriptor_cells_for_each(d, pos) \
+ for ((pos) = dvb_cell_list_descriptor_cells_first(d); \
+ (pos); \
+ (pos) = dvb_cell_list_descriptor_cells_next(d, pos))
+
+/**
+ * Iterator for the subcells field of a dvb_cell_list_entry.
+ *
+ * @param cell dvb_cell_list_entry pointer.
+ * @param pos Variable holding a pointer to the current dvb_subcell_list_entry.
+ */
+#define dvb_cell_list_entry_subcells_for_each(cell, pos) \
+ for ((pos) = dvb_cell_list_entry_subcells_first(cell); \
+ (pos); \
+ (pos) = dvb_cell_list_entry_subcells_next(cell, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_cell_list_entry*
+ dvb_cell_list_descriptor_cells_first(struct dvb_cell_list_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_cell_list_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_cell_list_descriptor));
+}
+
+static inline struct dvb_cell_list_entry*
+ dvb_cell_list_descriptor_cells_next(struct dvb_cell_list_descriptor *d,
+ struct dvb_cell_list_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_cell_list_entry) +
+ pos->subcell_info_loop_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_cell_list_entry *) next;
+}
+
+static inline struct dvb_subcell_list_entry*
+ dvb_cell_list_entry_subcells_first(struct dvb_cell_list_entry *d)
+{
+ if (d->subcell_info_loop_length == 0)
+ return NULL;
+
+ return (struct dvb_subcell_list_entry*)
+ ((uint8_t*) d + sizeof(struct dvb_cell_list_entry));
+}
+
+static inline struct dvb_subcell_list_entry*
+ dvb_cell_list_entry_subcells_next(struct dvb_cell_list_entry *d,
+ struct dvb_subcell_list_entry *pos)
+{
+ uint8_t *next = (uint8_t*) pos + sizeof(struct dvb_subcell_list_entry);
+ uint8_t *end = (uint8_t*) d +
+ sizeof(struct dvb_cell_list_entry) +
+ d->subcell_info_loop_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_subcell_list_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/component_descriptor.h b/lib/libucsi/dvb/component_descriptor.h
new file mode 100644
index 0000000..31d38e1
--- /dev/null
+++ b/lib/libucsi/dvb/component_descriptor.h
@@ -0,0 +1,147 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_COMPONENT_DESCRIPTOR
+#define _UCSI_DVB_COMPONENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * Possible values for stream_content.
+ */
+enum {
+ DVB_STREAM_CONTENT_VIDEO = 0x01,
+ DVB_STREAM_CONTENT_AUDIO = 0x02,
+ DVB_STREAM_CONTENT_SUBTITLE = 0x03,
+ DVB_STREAM_CONTENT_AC3 = 0x04,
+};
+
+/**
+ * Possible values for component_type.
+ */
+enum {
+ DVB_COMPONENT_TYPE_VIDEO_43_25Hz = 0x01,
+ DVB_COMPONENT_TYPE_VIDEO_169_PAN_25Hz = 0x02,
+ DVB_COMPONENT_TYPE_VIDEO_169_NOPAN_25Hz = 0x03,
+ DVB_COMPONENT_TYPE_VIDEO_GT169_25Hz = 0x04,
+
+ DVB_COMPONENT_TYPE_VIDEO_43_30Hz = 0x05,
+ DVB_COMPONENT_TYPE_VIDEO_169_PAN_30Hz = 0x06,
+ DVB_COMPONENT_TYPE_VIDEO_169_NOPAN_30Hz = 0x07,
+ DVB_COMPONENT_TYPE_VIDEO_GT169_30Hz = 0x08,
+
+ DVB_COMPONENT_TYPE_HDVIDEO_43_25Hz = 0x09,
+ DVB_COMPONENT_TYPE_HDVIDEO_169_PAN_25Hz = 0x0a,
+ DVB_COMPONENT_TYPE_HDVIDEO_169_NOPAN_25Hz = 0x0b,
+ DVB_COMPONENT_TYPE_HDVIDEO_GT169_25Hz = 0x0c,
+
+ DVB_COMPONENT_TYPE_HDVIDEO_43_30Hz = 0x0d,
+ DVB_COMPONENT_TYPE_HDVIDEO_169_PAN_30Hz = 0x0e,
+ DVB_COMPONENT_TYPE_HDVIDEO_169_NOPAN_30Hz = 0x0f,
+ DVB_COMPONENT_TYPE_HDVIDEO_GT169_30Hz = 0x10,
+
+ DVB_COMPONENT_TYPE_AUDIO_SINGLE_MONO = 0x01,
+ DVB_COMPONENT_TYPE_AUDIO_DUAL_MONO = 0x02,
+ DVB_COMPONENT_TYPE_AUDIO_STEREO = 0x03,
+ DVB_COMPONENT_TYPE_AUDIO_MULTI_LINGUAL_MULTI_CHAN= 0x04,
+ DVB_COMPONENT_TYPE_AUDIO_SURROUND = 0x05,
+ DVB_COMPONENT_TYPE_AUDIO_VISUAL_IMPAIRED = 0x40,
+ DVB_COMPONENT_TYPE_AUDIO_HARDHEAR = 0x41,
+ DVB_COMPONENT_TYPE_AUDIO_SUPPLEMENTARY = 0x42,
+
+ DVB_COMPONENT_TYPE_SUBTITLE_TELETEXT = 0x01,
+ DVB_COMPONENT_TYPE_SUBTITLE_ASSOC_TELETEXT = 0x02,
+ DVB_COMPONENT_TYPE_SUBTITLE_VBI = 0x03,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB = 0x10,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_43 = 0x11,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_169 = 0x12,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_2211 = 0x13,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR = 0x20,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_43 = 0x21,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_169 = 0x22,
+ DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_2211 = 0x23,
+};
+
+/**
+ * dvb_component_descriptor structure.
+ */
+struct dvb_component_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 4; ,
+ uint8_t stream_content : 4; );
+ uint8_t component_type;
+ uint8_t component_tag;
+ iso639lang_t language_code;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_component_descriptor.
+ *
+ * @param d Pointer to a generic descriptor.
+ * @return dvb_component_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_component_descriptor*
+ dvb_component_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_component_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_component_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of a dvb_component_descriptor.
+ *
+ * @param d dvb_component_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_component_descriptor_text(struct dvb_component_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_component_descriptor);
+}
+
+/**
+ * Determine the length of the text field of a dvb_component_descriptor.
+ *
+ * @param d dvb_component_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_component_descriptor_text_length(struct dvb_component_descriptor *d)
+{
+ return d->d.len - 6;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/content_descriptor.h b/lib/libucsi/dvb/content_descriptor.h
new file mode 100644
index 0000000..d2a63a0
--- /dev/null
+++ b/lib/libucsi/dvb/content_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_CONTENT_DESCRIPTOR
+#define _UCSI_DVB_CONTENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+// FIXME: the nibbles
+
+/**
+ * dvb_content_descriptor structure.
+ */
+struct dvb_content_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_content_nibble nibbles[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the nibbles field of a dvb_content_descriptor.
+ */
+struct dvb_content_nibble {
+ EBIT2(uint8_t content_nibble_level_1 : 4; ,
+ uint8_t content_nibble_level_2 : 4; );
+ EBIT2(uint8_t user_nibble_1 : 4; ,
+ uint8_t user_nibble_2 : 4; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_content_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_content_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_content_descriptor*
+ dvb_content_descriptor_codec(struct descriptor* d)
+{
+ if (d->len % sizeof(struct dvb_content_nibble))
+ return NULL;
+
+ return (struct dvb_content_descriptor*) d;
+}
+
+/**
+ * Iterator for the nibbles field of a dvb_content_descriptor.
+ *
+ * @param d dvb_content_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_content_nibble.
+ */
+#define dvb_content_descriptor_nibbles_for_each(d, pos) \
+ for ((pos) = dvb_content_descriptor_nibbles_first(d); \
+ (pos); \
+ (pos) = dvb_content_descriptor_nibbles_next(d, pos))
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_content_nibble*
+ dvb_content_descriptor_nibbles_first(struct dvb_content_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_content_nibble *)
+ ((uint8_t*) d + sizeof(struct dvb_content_descriptor));
+}
+
+static inline struct dvb_content_nibble*
+ dvb_content_descriptor_nibbles_next(struct dvb_content_descriptor *d,
+ struct dvb_content_nibble *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_content_nibble);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_content_nibble *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/content_identifier_descriptor.h b/lib/libucsi/dvb/content_identifier_descriptor.h
new file mode 100644
index 0000000..c2cf9ea
--- /dev/null
+++ b/lib/libucsi/dvb/content_identifier_descriptor.h
@@ -0,0 +1,233 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_CONTENT_IDENTIFIER_DESCRIPTOR
+#define _UCSI_DVB_CONTENT_IDENTIFIER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+
+/**
+ * Possible values for the crid_type.
+ */
+enum {
+ DVB_CRID_TYPE_NONE = 0x00,
+ DVB_CRID_TYPE_ITEM = 0x01,
+ DVB_CRID_TYPE_SERIES = 0x02,
+ DVB_CRID_TYPE_RECOMMENDATION = 0x03,
+};
+
+/**
+ * Possible values for the crid_location.
+ */
+enum {
+ DVB_CRID_LOCATION_THIS_DESCRIPTOR = 0x00,
+ DVB_CRID_LOCATION_CIT = 0x01,
+};
+
+/**
+ * dvb_content_identifier_descriptor structure.
+ */
+struct dvb_content_identifier_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_content_identifier_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a dvb_content_identifier_descriptor.
+ */
+struct dvb_content_identifier_entry {
+ EBIT2(uint8_t crid_type : 6; ,
+ uint8_t crid_location : 2; );
+ /* struct dvb_content_identifier_data_00 data0 */
+ /* struct dvb_content_identifier_data_01 data1 */
+} __ucsi_packed;
+
+/**
+ * The data if crid_location == 0
+ */
+struct dvb_content_identifier_entry_data_0 {
+ uint8_t crid_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * The data if crid_location == 1
+ */
+struct dvb_content_identifier_entry_data_1 {
+ uint16_t crid_ref;
+} __ucsi_packed;
+
+
+/**
+ * Process a dvb_content_identifier_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_content_identifier_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_content_identifier_descriptor*
+ dvb_content_identifier_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len + 2;
+ uint32_t pos = 2;
+ uint8_t *buf = (uint8_t*) d;
+
+ while(pos < len) {
+ struct dvb_content_identifier_entry *e =
+ (struct dvb_content_identifier_entry*) (buf + pos);
+
+ if (len < (pos+1))
+ return NULL;
+ pos++;
+
+ switch(e->crid_location) {
+ case 0:
+ if (len < (pos + 1))
+ return NULL;
+ if (len < (pos + 1 + buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ break;
+
+ case 1:
+ if (len < (pos+2))
+ return NULL;
+ bswap16(buf+pos);
+ break;
+ }
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct dvb_content_identifier_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field of a dvb_content_identifier_descriptor.
+ *
+ * @param d dvb_content_identifier_descriptor pointer.
+ * @param pos Variable holding a pointer to the current dvb_content_identifier_entry.
+ */
+#define dvb_content_identifier_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_content_identifier_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_content_identifier_descriptor_entries_next(d, pos))
+
+/**
+ * Accessor for the data0 field of a dvb_content_identifier_entry.
+ *
+ * @param d dvb_content_identifier_entry pointer.
+ * @return Pointer, or NULL on error.
+ */
+static inline struct dvb_content_identifier_entry_data_0*
+ dvb_content_identifier_entry_data_0(struct dvb_content_identifier_entry *d)
+{
+ if (d->crid_location != 0)
+ return NULL;
+ return (struct dvb_content_identifier_entry_data_0*)
+ ((uint8_t*) d + sizeof(struct dvb_content_identifier_entry));
+}
+/**
+ * Accessor for the data field of a dvb_content_identifier_entry_data_0.
+ *
+ * @param d dvb_content_identifier_entry_data_0 pointer.
+ * @return Pointer, or NULL on error.
+ */
+static inline uint8_t*
+ dvb_content_identifier_entry_data_0_data(struct dvb_content_identifier_entry_data_0 *d)
+{
+ return ((uint8_t*) d + sizeof(struct dvb_content_identifier_entry_data_0));
+}
+
+/**
+ * Accessor for the data1 field of a dvb_content_identifier_entry.
+ *
+ * @param d dvb_content_identifier_entry pointer.
+ * @return Pointer, or NULL on error.
+ */
+static inline struct dvb_content_identifier_entry_data_1*
+ dvb_content_identifier_entry_data_1(struct dvb_content_identifier_entry *d)
+{
+ if (d->crid_location != 1)
+ return NULL;
+ return (struct dvb_content_identifier_entry_data_1*)
+ ((uint8_t*) d + sizeof(struct dvb_content_identifier_entry));
+}
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_content_identifier_entry*
+ dvb_content_identifier_descriptor_entries_first(struct dvb_content_identifier_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_content_identifier_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_content_identifier_descriptor));
+}
+
+static inline struct dvb_content_identifier_entry*
+ dvb_content_identifier_descriptor_entries_next(struct dvb_content_identifier_descriptor *d,
+ struct dvb_content_identifier_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_content_identifier_entry);
+
+ if (next >= end)
+ return NULL;
+
+ switch(pos->crid_location) {
+ case 0:
+ if ((next+2) >= end)
+ return NULL;
+ if ((next+2+next[1]) >= end)
+ return NULL;
+ break;
+
+ case 1:
+ if ((next+3) >= end)
+ return NULL;
+ break;
+ }
+
+ return (struct dvb_content_identifier_entry*) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/country_availability_descriptor.h b/lib/libucsi/dvb/country_availability_descriptor.h
new file mode 100644
index 0000000..65b1661
--- /dev/null
+++ b/lib/libucsi/dvb/country_availability_descriptor.h
@@ -0,0 +1,120 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_COUNTRY_AVAILABILITY_DESCRIPTOR
+#define _UCSI_DVB_COUNTRY_AVAILABILITY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_country_availability_descriptor structure.
+ */
+struct dvb_country_availability_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t country_availability_flag : 1; ,
+ uint8_t reserved : 7; );
+ /* struct dvb_country_availability_entry countries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the countries field of a dvb_country_availability_descriptor.
+ */
+struct dvb_country_availability_entry {
+ iso639country_t country_code;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_country_availability_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_country_availability_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_country_availability_descriptor*
+ dvb_country_availability_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+
+ if (len < (sizeof(struct dvb_country_availability_descriptor) - 2))
+ return NULL;
+
+ if ((len - 1) % sizeof(struct dvb_country_availability_entry))
+ return NULL;
+
+ return (struct dvb_country_availability_descriptor*) d;
+}
+
+/**
+ * Iterator for the countries field of a dvb_country_availability_descriptor.
+ *
+ * @param d dvb_country_availability_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_country_availability_entry.
+ */
+#define dvb_country_availability_descriptor_countries_for_each(d, pos) \
+ for ((pos) = dvb_country_availability_descriptor_countries_first(d); \
+ (pos); \
+ (pos) = dvb_country_availability_descriptor_countries_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_country_availability_entry*
+ dvb_country_availability_descriptor_countries_first(struct dvb_country_availability_descriptor *d)
+{
+ if (d->d.len == 1)
+ return NULL;
+
+ return (struct dvb_country_availability_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_country_availability_descriptor));
+}
+
+static inline struct dvb_country_availability_entry*
+ dvb_country_availability_descriptor_countries_next(struct dvb_country_availability_descriptor *d,
+ struct dvb_country_availability_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_country_availability_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_country_availability_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/data_broadcast_descriptor.h b/lib/libucsi/dvb/data_broadcast_descriptor.h
new file mode 100644
index 0000000..069e1db
--- /dev/null
+++ b/lib/libucsi/dvb/data_broadcast_descriptor.h
@@ -0,0 +1,139 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_DATA_BROADCAST_DESCRIPTOR
+#define _UCSI_DVB_DATA_BROADCAST_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_data_broadcast_descriptor structure.
+ */
+struct dvb_data_broadcast_descriptor {
+ struct descriptor d;
+
+ uint16_t data_broadcast_id;
+ uint8_t component_tag;
+ uint8_t selector_length;
+ /* uint8_t selector[] */
+ /* struct dvb_data_broadcast_descriptor_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * Second part of a dvb_data_broadcast_descriptor following the variable length selector field.
+ */
+struct dvb_data_broadcast_descriptor_part2 {
+ iso639lang_t language_code;
+ uint8_t text_length;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_data_broadcast_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_data_broadcast_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_data_broadcast_descriptor*
+ dvb_data_broadcast_descriptor_codec(struct descriptor* d)
+{
+ struct dvb_data_broadcast_descriptor *p =
+ (struct dvb_data_broadcast_descriptor *) d;
+ struct dvb_data_broadcast_descriptor_part2 *p2;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = sizeof(struct dvb_data_broadcast_descriptor) - 2;
+ uint32_t len = d->len;
+
+ if (pos > len)
+ return NULL;
+
+ bswap16(buf + 2);
+
+ pos += p->selector_length;
+
+ if (pos > len)
+ return NULL;
+
+ p2 = (struct dvb_data_broadcast_descriptor_part2*) (buf + 2 + pos);
+
+ pos += sizeof(struct dvb_data_broadcast_descriptor_part2);
+
+ if (pos > len)
+ return NULL;
+
+ pos += p2->text_length;
+
+ if (pos != len)
+ return NULL;
+
+ return p;
+}
+
+/**
+ * Accessor for the selector field of a dvb_data_broadcast_descriptor.
+ *
+ * @param d dvb_data_broadcast_descriptor pointer.
+ * @return pointer to the field.
+ */
+static inline uint8_t *
+ dvb_data_broadcast_descriptor_selector(struct dvb_data_broadcast_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_data_broadcast_descriptor);
+}
+
+/**
+ * Accessor for the second part of a dvb_data_broadcast_descriptor.
+ *
+ * @param d dvb_data_broadcast_descriptor pointer.
+ * @return dvb_data_broadcast_descriptor_part2 pointer.
+ */
+static inline struct dvb_data_broadcast_descriptor_part2 *
+ dvb_data_broadcast_descriptor_part2(struct dvb_data_broadcast_descriptor *d)
+{
+ return (struct dvb_data_broadcast_descriptor_part2*)
+ ((uint8_t*) d + sizeof(struct dvb_data_broadcast_descriptor) +
+ d->selector_length);
+}
+
+/**
+ * Accessor for the text field in a dvb_data_broadcast_descriptor_part2.
+ *
+ * @param d dvb_data_broadcast_descriptor_part2 pointer.
+ * @return pointer to the field.
+ */
+static inline uint8_t *
+ dvb_data_broadcast_descriptor_part2_text(struct dvb_data_broadcast_descriptor_part2 *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_data_broadcast_descriptor_part2);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/data_broadcast_id_descriptor.h b/lib/libucsi/dvb/data_broadcast_id_descriptor.h
new file mode 100644
index 0000000..446927c
--- /dev/null
+++ b/lib/libucsi/dvb/data_broadcast_id_descriptor.h
@@ -0,0 +1,221 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_DATA_BROADCAST_ID_DESCRIPTOR
+#define _UCSI_DVB_DATA_BROADCAST_ID_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for data_broadcast_id.
+ */
+enum {
+ DVB_BROADCAST_ID_DATA_PIPE = 0X0001,
+ DVB_BROADCAST_ID_ASYNCHRONOUS_DATA_STREAM = 0X0002,
+ DVB_BROADCAST_ID_SYNCHRONOUS_DATA_STREAM = 0X0003,
+ DVB_BROADCAST_ID_SYNCHRONISED_DATA_STREAM = 0X0004,
+ DVB_BROADCAST_ID_MULTI_PROTOCOL_ENCAPSULATION = 0X0005,
+ DVB_BROADCAST_ID_DATA_CAROUSEL = 0X0006,
+ DVB_BROADCAST_ID_OBJECT_CAROUSEL = 0X0007,
+ DVB_BROADCAST_ID_DVB_ATM_STREAMS = 0X0008,
+ DVB_BROADCAST_ID_HIGHER_PROTOCOLS = 0X0009,
+ DVB_BROADCAST_ID_SOFTWARE_UPDATE = 0x000A,
+ DVB_BROADCAST_ID_IP_MAC_NOTIFICATION_TABLE = 0x000B,
+};
+
+/**
+ * dvb_data_broadcast_id_descriptor structure.
+ */
+struct dvb_data_broadcast_id_descriptor {
+ struct descriptor d;
+
+ uint16_t data_broadcast_id;
+ /* uint8_t id_selector_byte[] */
+} __ucsi_packed;
+
+/**
+ * id_selector_byte for 0x000b data_broadcast_id (IP/MAC Notification Table).
+ */
+struct dvb_id_selector_byte_000b {
+ uint8_t platform_id_data_length;
+ /* struct dvb_ip_mac_notification_info infos[] */
+ /* uint8_t private_data[] */
+} __ucsi_packed;
+
+/**
+ * Entries in the infos field of a dvb_id_selector_byte_0b.
+ */
+struct dvb_ip_mac_notification_info {
+ EBIT2(uint32_t platform_id : 24; ,
+ uint8_t action_type : 8; );
+ EBIT3(uint8_t reserved : 2; ,
+ uint8_t INT_versioning_flag : 1; ,
+ uint8_t INT_version : 5; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_data_broadcast_id_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_data_broadcast_id_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_data_broadcast_id_descriptor*
+ dvb_data_broadcast_id_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_data_broadcast_id_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+
+ return (struct dvb_data_broadcast_id_descriptor*) d;
+}
+
+/**
+ * Accessor for the selector_byte field of a dvb_data_broadcast_id_descriptor.
+ *
+ * @param d dvb_data_broadcast_id_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_data_broadcast_id_descriptor_id_selector_byte(struct dvb_data_broadcast_id_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_data_broadcast_id_descriptor);
+}
+
+/**
+ * Determine the length of the selector_byte field of a dvb_data_broadcast_id_descriptor.
+ *
+ * @param d dvb_data_broadcast_id_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_data_broadcast_id_descriptor_id_selector_byte_length(struct dvb_data_broadcast_id_descriptor *d)
+{
+ return d->d.len - 2;
+}
+
+/**
+ * Accessor for a dvb_id_selector_byte_000b pointer.
+ *
+ * @param d dvb_data_broadcast_id_descriptor pointer.
+ * @return Pointer to the data field.
+ */
+static inline struct dvb_id_selector_byte_000b *
+ dvb_id_selector_byte_000b(struct dvb_data_broadcast_id_descriptor *d)
+{
+ if (d->data_broadcast_id != DVB_BROADCAST_ID_IP_MAC_NOTIFICATION_TABLE)
+ return NULL;
+ return (struct dvb_id_selector_byte_000b *) dvb_data_broadcast_id_descriptor_id_selector_byte(d);
+}
+
+/**
+ * Iterator for the dvb_ip_mac_notification_info field of a dvb_id_selector_byte_000b.
+ *
+ * @param id_selector_byte dvb_id_selector_byte_000b pointer.
+ * @param pos Variable containing a pointer to the current dvb_ip_mac_notification_info.
+ */
+#define dvb_id_selector_byte_000b_ip_mac_notification_info_for_each(id_selector_byte, pos) \
+ for ((pos) = dvb_ip_mac_notification_info_first(id_selector_byte); \
+ (pos); \
+ (pos) = dvb_ip_mac_notification_info_next(id_selector_byte, pos))
+
+/**
+ * Length of the private_data field of a dvb_id_selector_byte_000b.
+ *
+ * @param d descriptor pointer.
+ * @param i dvb_id_selector_byte_000b pointer.
+ * @return Length of the field.
+ */
+static inline uint8_t
+ dvb_id_selector_byte_000b_private_data_length(struct descriptor *d,
+ struct dvb_id_selector_byte_000b *i)
+{
+ return (uint8_t) (d->len -
+ sizeof(struct descriptor) -
+ i->platform_id_data_length -
+ sizeof(struct dvb_id_selector_byte_000b));
+}
+
+/**
+ * Accessor for the private_data field of a dvb_id_selector_byte_000b.
+ *
+ * @param d descriptor pointer.
+ * @param i dvb_id_selector_byte_000b pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_id_selector_byte_000b_private_data(struct descriptor *d,
+ struct dvb_id_selector_byte_000b *i)
+{
+ if (dvb_id_selector_byte_000b_private_data_length(d, i) <= 0)
+ return NULL;
+
+ return (uint8_t *) i + i->platform_id_data_length + sizeof(struct dvb_id_selector_byte_000b);
+}
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ip_mac_notification_info *
+ dvb_ip_mac_notification_info_first(struct dvb_id_selector_byte_000b *d)
+{
+ if (d->platform_id_data_length == 0)
+ return NULL;
+
+ bswap32((uint8_t *) d + sizeof(struct dvb_id_selector_byte_000b));
+
+ return (struct dvb_ip_mac_notification_info *) ((uint8_t *) d + sizeof(struct dvb_id_selector_byte_000b));
+}
+
+static inline struct dvb_ip_mac_notification_info *
+ dvb_ip_mac_notification_info_next(struct dvb_id_selector_byte_000b *d,
+ struct dvb_ip_mac_notification_info *pos)
+{
+ uint8_t *end = (uint8_t *) d + d->platform_id_data_length;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_id_selector_byte_000b) +
+ sizeof(struct dvb_ip_mac_notification_info);
+
+ if (next >= end)
+ return NULL;
+
+ bswap32(next);
+
+ return (struct dvb_ip_mac_notification_info *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#include <libucsi/dvb/mhp_data_broadcast_id_descriptor.h>
diff --git a/lib/libucsi/dvb/default_authority_descriptor.h b/lib/libucsi/dvb/default_authority_descriptor.h
new file mode 100644
index 0000000..0b0ba73
--- /dev/null
+++ b/lib/libucsi/dvb/default_authority_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_DEFAULT_AUTHORITY_DESCRIPTOR
+#define _UCSI_DVB_DEFAULT_AUTHORITY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_default_authority_descriptor structure.
+ */
+struct dvb_default_authority_descriptor {
+ struct descriptor d;
+
+ /* char name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_default_authority_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_default_authority_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_default_authority_descriptor*
+ dvb_default_authority_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_default_authority_descriptor*) d;
+}
+
+/**
+ * Accessor for the name field in a dvb_default_authority_descriptor.
+ *
+ * @param d dvb_default_authority_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_default_authority_descriptor_name(struct dvb_default_authority_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_default_authority_descriptor);
+}
+
+/**
+ * Calculate the length of the name field in a dvb_default_authority_descriptor.
+ *
+ * @param d dvb_default_authority_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_default_authority_descriptor_name_length(struct dvb_default_authority_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/descriptor.h b/lib/libucsi/dvb/descriptor.h
new file mode 100644
index 0000000..303e17a
--- /dev/null
+++ b/lib/libucsi/dvb/descriptor.h
@@ -0,0 +1,229 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_DESCRIPTOR_H
+#define _UCSI_DVB_DESCRIPTOR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/dvb/ac3_descriptor.h>
+#include <libucsi/dvb/adaptation_field_data_descriptor.h>
+#include <libucsi/dvb/ancillary_data_descriptor.h>
+#include <libucsi/dvb/announcement_support_descriptor.h>
+#include <libucsi/dvb/application_signalling_descriptor.h>
+#include <libucsi/dvb/bouquet_name_descriptor.h>
+#include <libucsi/dvb/ca_identifier_descriptor.h>
+#include <libucsi/dvb/cable_delivery_descriptor.h>
+#include <libucsi/dvb/cell_frequency_link_descriptor.h>
+#include <libucsi/dvb/cell_list_descriptor.h>
+#include <libucsi/dvb/component_descriptor.h>
+#include <libucsi/dvb/content_descriptor.h>
+#include <libucsi/dvb/content_identifier_descriptor.h>
+#include <libucsi/dvb/country_availability_descriptor.h>
+#include <libucsi/dvb/data_broadcast_descriptor.h>
+#include <libucsi/dvb/data_broadcast_id_descriptor.h>
+#include <libucsi/dvb/default_authority_descriptor.h>
+#include <libucsi/dvb/dsng_descriptor.h>
+#include <libucsi/dvb/extended_event_descriptor.h>
+#include <libucsi/dvb/frequency_list_descriptor.h>
+#include <libucsi/dvb/ip_mac_platform_name_descriptor.h>
+#include <libucsi/dvb/ip_mac_platform_provider_name_descriptor.h>
+#include <libucsi/dvb/ip_mac_stream_location_descriptor.h>
+#include <libucsi/dvb/linkage_descriptor.h>
+#include <libucsi/dvb/local_time_offset_descriptor.h>
+#include <libucsi/dvb/mosaic_descriptor.h>
+#include <libucsi/dvb/multilingual_bouquet_name_descriptor.h>
+#include <libucsi/dvb/multilingual_component_descriptor.h>
+#include <libucsi/dvb/multilingual_network_name_descriptor.h>
+#include <libucsi/dvb/multilingual_service_name_descriptor.h>
+#include <libucsi/dvb/network_name_descriptor.h>
+#include <libucsi/dvb/nvod_reference_descriptor.h>
+#include <libucsi/dvb/parental_rating_descriptor.h>
+#include <libucsi/dvb/partial_transport_stream_descriptor.h>
+#include <libucsi/dvb/pdc_descriptor.h>
+#include <libucsi/dvb/private_data_specifier_descriptor.h>
+#include <libucsi/dvb/related_content_descriptor.h>
+#include <libucsi/dvb/satellite_delivery_descriptor.h>
+#include <libucsi/dvb/s2_satellite_delivery_descriptor.h>
+#include <libucsi/dvb/scrambling_descriptor.h>
+#include <libucsi/dvb/service_availability_descriptor.h>
+#include <libucsi/dvb/service_descriptor.h>
+#include <libucsi/dvb/service_identifier_descriptor.h>
+#include <libucsi/dvb/service_list_descriptor.h>
+#include <libucsi/dvb/service_move_descriptor.h>
+#include <libucsi/dvb/short_event_descriptor.h>
+#include <libucsi/dvb/short_smoothing_buffer_descriptor.h>
+#include <libucsi/dvb/stream_identifier_descriptor.h>
+#include <libucsi/dvb/stuffing_descriptor.h>
+#include <libucsi/dvb/subtitling_descriptor.h>
+#include <libucsi/dvb/target_ip_address_descriptor.h>
+#include <libucsi/dvb/target_ipv6_address_descriptor.h>
+#include <libucsi/dvb/target_ip_slash_descriptor.h>
+#include <libucsi/dvb/target_ip_source_slash_descriptor.h>
+#include <libucsi/dvb/target_ipv6_slash_descriptor.h>
+#include <libucsi/dvb/target_ipv6_source_slash_descriptor.h>
+#include <libucsi/dvb/telephone_descriptor.h>
+#include <libucsi/dvb/teletext_descriptor.h>
+#include <libucsi/dvb/terrestrial_delivery_descriptor.h>
+#include <libucsi/dvb/time_shifted_event_descriptor.h>
+#include <libucsi/dvb/time_shifted_service_descriptor.h>
+#include <libucsi/dvb/transport_stream_descriptor.h>
+#include <libucsi/dvb/tva_id_descriptor.h>
+#include <libucsi/dvb/vbi_data_descriptor.h>
+#include <libucsi/dvb/vbi_teletext_descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * The following are disabled because support is incomplete just now.
+ */
+/*
+#include <libucsi/dvb/rnt_rar_over_dvb_stream_descriptor.h>
+#include <libucsi/dvb/rnt_rar_over_ip_descriptor.h>
+#include <libucsi/dvb/rnt_rnt_scan_descriptor.h>
+#include <libucsi/dvb/ait_application_descriptor.h>
+#include <libucsi/dvb/ait_application_name_descriptor.h>
+#include <libucsi/dvb/ait_external_application_authorisation_descriptor.h>
+#include <libucsi/dvb/ait_application_icons_descriptor.h>
+*/
+
+/**
+ * The following are not implemented just now
+ */
+/*
+#include <libucsi/dvb/ait_transport_protocol_descriptor.h>
+#include <libucsi/dvb/ait_dvb_j_application_descriptor.h>
+#include <libucsi/dvb/ait_dvb_j_application_location_descriptor.h>
+#include <libucsi/dvb/ait_dvb_html_application_descriptor.h>
+#include <libucsi/dvb/ait_dvb_html_application_location_descriptor.h>
+#include <libucsi/dvb/ait_dvb_html_application_boundary_descriptor.h>
+#include <libucsi/dvb/ait_prefetch_descriptor.h>
+#include <libucsi/dvb/ait_dii_location_descriptor.h>
+#include <libucsi/dvb/ait_ip_signalling_descriptor.h>
+*/
+
+/**
+ * Enumeration of DVB descriptor tags.
+ */
+enum dvb_descriptor_tag {
+ dtag_dvb_network_name = 0x40,
+ dtag_dvb_service_list = 0x41,
+ dtag_dvb_stuffing = 0x42,
+ dtag_dvb_satellite_delivery_system = 0x43,
+ dtag_dvb_cable_delivery_system = 0x44,
+ dtag_dvb_vbi_data = 0x45,
+ dtag_dvb_vbi_teletext = 0x46,
+ dtag_dvb_bouquet_name = 0x47,
+ dtag_dvb_service = 0x48,
+ dtag_dvb_country_availability = 0x49,
+ dtag_dvb_linkage = 0x4a,
+ dtag_dvb_nvod_reference = 0x4b,
+ dtag_dvb_time_shifted_service = 0x4c,
+ dtag_dvb_short_event = 0x4d,
+ dtag_dvb_extended_event = 0x4e,
+ dtag_dvb_time_shifted_event = 0x4f,
+ dtag_dvb_component = 0x50,
+ dtag_dvb_mosaic = 0x51,
+ dtag_dvb_stream_identifier = 0x52,
+ dtag_dvb_ca_identifier = 0x53,
+ dtag_dvb_content = 0x54,
+ dtag_dvb_parental_rating = 0x55,
+ dtag_dvb_teletext = 0x56,
+ dtag_dvb_telephone = 0x57,
+ dtag_dvb_local_time_offset = 0x58,
+ dtag_dvb_subtitling = 0x59,
+ dtag_dvb_terrestial_delivery_system = 0x5a,
+ dtag_dvb_multilingual_network_name = 0x5b,
+ dtag_dvb_multilingual_bouquet_name = 0x5c,
+ dtag_dvb_multilingual_service_name = 0x5d,
+ dtag_dvb_multilingual_component = 0x5e,
+ dtag_dvb_private_data_specifier = 0x5f,
+ dtag_dvb_service_move = 0x60,
+ dtag_dvb_short_smoothing_buffer = 0x61,
+ dtag_dvb_frequency_list = 0x62,
+ dtag_dvb_partial_transport_stream = 0x63,
+ dtag_dvb_data_broadcast = 0x64,
+ dtag_dvb_scrambling = 0x65,
+ dtag_dvb_data_broadcast_id = 0x66,
+ dtag_dvb_transport_stream = 0x67,
+ dtag_dvb_dsng = 0x68,
+ dtag_dvb_pdc = 0x69,
+ dtag_dvb_ac3 = 0x6a,
+ dtag_dvb_ancillary_data = 0x6b,
+ dtag_dvb_cell_list = 0x6c,
+ dtag_dvb_cell_frequency_link = 0x6d,
+ dtag_dvb_announcement_support = 0x6e,
+ dtag_dvb_application_signalling = 0x6f,
+ dtag_dvb_adaptation_field_data = 0x70,
+ dtag_dvb_service_identifier = 0x71,
+ dtag_dvb_service_availability = 0x72,
+ dtag_dvb_default_authority = 0x73,
+ dtag_dvb_related_content = 0x74,
+ dtag_dvb_tva_id = 0x75,
+ dtag_dvb_content_identifier = 0x76,
+ dtag_dvb_time_slice_fec_identifier = 0x77,
+ dtag_dvb_ecm_repetition_rate = 0x78,
+ dtag_dvb_s2_satellite_delivery_descriptor= 0x79,
+ dtag_dvb_enhanced_ac3_descriptor = 0x7a,
+ dtag_dvb_dts_descriptor = 0x7b,
+ dtag_dvb_aac_descriptor = 0x7c,
+ dtag_dvb_extension_descriptor = 0x7f,
+
+ /* descriptors which may only appear in an RNT */
+ dtag_dvb_rnt_rar_over_dvb_stream = 0x40,
+ dtag_dvb_rnt_rar_over_ip = 0x41,
+ dtag_dvb_rnt_rnt_scan = 0x42,
+
+ /* descriptors which may only appear in an AIT */
+ dtag_dvb_ait_application = 0x00,
+ dtag_dvb_ait_application_name = 0x01,
+ dtag_dvb_ait_transport_protocol = 0x02,
+ dtag_dvb_ait_dvb_j_application = 0x03,
+ dtag_dvb_ait_dvb_j_application_location = 0x04,
+ dtag_dvb_ait_external_application_authorisation = 0x05,
+ dtag_dvb_ait_dvb_html_application = 0x08,
+ dtag_dvb_ait_dvb_html_application_location = 0x09,
+ dtab_dvb_ait_dvb_html_application_boundary = 0x0a,
+ dtag_dvb_ait_application_icons = 0x0b,
+ dtag_dvb_ait_prefetch = 0x0c,
+ dtag_dvb_ait_dii_location = 0x0d,
+ dtag_dvb_ait_ip_signalling = 0x11,
+
+ /* descriptors which may only appear in INT */
+ dtag_dvb_target_ip_address = 0x09,
+ dtag_dvb_target_ipv6_address = 0x0a,
+ dtag_dvb_ip_mac_platform_name = 0x0c,
+ dtag_dvb_ip_mac_platform_provider_name = 0x0d,
+ dtag_dvb_target_ip_slash = 0x0f,
+ dtag_dvb_target_ip_source_slash = 0x10,
+ dtag_dvb_target_ipv6_slash = 0x11,
+ dtag_dvb_target_ipv6_source_slash = 0x12,
+ dtag_dvb_ip_mac_stream_location = 0x13,
+
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/dit_section.c b/lib/libucsi/dvb/dit_section.c
new file mode 100644
index 0000000..4f69d4e
--- /dev/null
+++ b/lib/libucsi/dvb/dit_section.c
@@ -0,0 +1,32 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/dit_section.h>
+
+struct dvb_dit_section * dvb_dit_section_codec(struct section * section)
+{
+ struct dvb_dit_section * ret = (struct dvb_dit_section *)section;
+
+ if (section->length < 1)
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/dit_section.h b/lib/libucsi/dvb/dit_section.h
new file mode 100644
index 0000000..69fce4f
--- /dev/null
+++ b/lib/libucsi/dvb/dit_section.h
@@ -0,0 +1,54 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_DIT_SECTION_H
+#define _UCSI_DVB_DIT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_dit_section structure.
+ */
+struct dvb_dit_section {
+ struct section head;
+
+ EBIT2(uint8_t transition_flag : 1; ,
+ uint8_t reserved : 7; );
+};
+
+/**
+ * Process a dvb_dit_section.
+ *
+ * @param section Pointer to a generic section header.
+ * @return Pointer to a dvb_dit_section, or NULL on error.
+ */
+struct dvb_dit_section * dvb_dit_section_codec(struct section *section);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/dsng_descriptor.h b/lib/libucsi/dvb/dsng_descriptor.h
new file mode 100644
index 0000000..6fd369b
--- /dev/null
+++ b/lib/libucsi/dvb/dsng_descriptor.h
@@ -0,0 +1,80 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_DSNG_DESCRIPTOR
+#define _UCSI_DVB_DSNG_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_dsng_descriptor structure.
+ */
+struct dvb_dsng_descriptor {
+ struct descriptor d;
+
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_dsng_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to a dvb_dsng_descriptor, or NULL on error.
+ */
+static inline struct dvb_dsng_descriptor*
+ dvb_dsng_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_dsng_descriptor*) d;
+}
+
+/**
+ * Accessor for the data field in a dvb_dsng_descriptor.
+ *
+ * @param d dvb_dsng_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *dvb_dsng_descriptor_data(struct dvb_dsng_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_dsng_descriptor);
+}
+
+/**
+ * Determine the length of the data field in a dvb_dsng_descriptor.
+ *
+ * @param d dvb_dsng_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int dvb_dsng_descriptor_data_length(struct dvb_dsng_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/eit_section.c b/lib/libucsi/dvb/eit_section.c
new file mode 100644
index 0000000..97b0261
--- /dev/null
+++ b/lib/libucsi/dvb/eit_section.c
@@ -0,0 +1,63 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/eit_section.h>
+
+struct dvb_eit_section *dvb_eit_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct dvb_eit_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+ bswap16(buf + pos);
+ pos += 4;
+
+ while (pos < len) {
+ struct dvb_eit_event * event =
+ (struct dvb_eit_event *) (buf + pos);
+
+ if ((pos + sizeof(struct dvb_eit_event)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 10);
+
+ pos += sizeof(struct dvb_eit_event);
+
+ if ((pos + event->descriptors_loop_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, event->descriptors_loop_length))
+ return NULL;
+
+ pos += event->descriptors_loop_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct dvb_eit_section *) ext;
+}
diff --git a/lib/libucsi/dvb/eit_section.h b/lib/libucsi/dvb/eit_section.h
new file mode 100644
index 0000000..a2f3e4f
--- /dev/null
+++ b/lib/libucsi/dvb/eit_section.h
@@ -0,0 +1,160 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_EIT_SECTION_H
+#define _UCSI_DVB_EIT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+#include <libucsi/dvb/types.h>
+
+
+/**
+ * dvb_eit_section structure.
+ */
+struct dvb_eit_section {
+ struct section_ext head;
+
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ uint8_t segment_last_section_number;
+ uint8_t last_table_id;
+ /* struct eit_event events[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the events field of a dvb_eit_section.
+ */
+struct dvb_eit_event {
+ uint16_t event_id;
+ dvbdate_t start_time;
+ dvbduration_t duration;
+ EBIT3(uint16_t running_status : 3; ,
+ uint16_t free_ca_mode : 1; ,
+ uint16_t descriptors_loop_length:12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_eit_section.
+ *
+ * @param section Pointer to a generic section_ext structure.
+ * @return Pointer to a dvb_eit_section, or NULL on error.
+ */
+struct dvb_eit_section *dvb_eit_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the service_id field of an EIT.
+ *
+ * @param eit EIT pointer.
+ * @return The service_id.
+ */
+static inline uint16_t dvb_eit_section_service_id(struct dvb_eit_section *eit)
+{
+ return eit->head.table_id_ext;
+}
+
+/**
+ * Iterator for the events field of a dvb_eit_section.
+ *
+ * @param eit dvb_eit_section pointer.
+ * @param pos Variable containing a pointer to the current dvb_eit_event.
+ */
+#define dvb_eit_section_events_for_each(eit, pos) \
+ for ((pos) = dvb_eit_section_events_first(eit); \
+ (pos); \
+ (pos) = dvb_eit_section_events_next(eit, pos))
+
+/**
+ * Iterator for the descriptors field of a dvb_eit_event.
+ *
+ * @param eit dvb_eit_event pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define dvb_eit_event_descriptors_for_each(event, pos) \
+ for ((pos) = dvb_eit_event_descriptors_first(event); \
+ (pos); \
+ (pos) = dvb_eit_event_descriptors_next(event, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_eit_event *
+ dvb_eit_section_events_first(struct dvb_eit_section *eit)
+{
+ size_t pos = sizeof(struct dvb_eit_section);
+
+ if (pos >= section_ext_length(&eit->head))
+ return NULL;
+
+ return (struct dvb_eit_event*) ((uint8_t *) eit + pos);
+}
+
+static inline struct dvb_eit_event *
+ dvb_eit_section_events_next(struct dvb_eit_section *eit,
+ struct dvb_eit_event *pos)
+{
+ uint8_t *end = (uint8_t*) eit + section_ext_length(&eit->head);
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_eit_event) +
+ pos->descriptors_loop_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_eit_event *) next;
+}
+
+static inline struct descriptor *
+ dvb_eit_event_descriptors_first(struct dvb_eit_event * t)
+{
+ if (t->descriptors_loop_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) t + sizeof(struct dvb_eit_event));
+}
+
+static inline struct descriptor *
+ dvb_eit_event_descriptors_next(struct dvb_eit_event * t,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) t + sizeof(struct dvb_eit_event),
+ t->descriptors_loop_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/extended_event_descriptor.h b/lib/libucsi/dvb/extended_event_descriptor.h
new file mode 100644
index 0000000..bba04b0
--- /dev/null
+++ b/lib/libucsi/dvb/extended_event_descriptor.h
@@ -0,0 +1,232 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_EXTENDED_EVENT_DESCRIPTOR
+#define _UCSI_DVB_EXTENDED_EVENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_extended_event_descriptor structure.
+ */
+struct dvb_extended_event_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t descriptor_number : 4; ,
+ uint8_t last_descriptor_number : 4; );
+ iso639lang_t language_code;
+ uint8_t length_of_items;
+ /* struct dvb_extended_event_item items[] */
+ /* struct dvb_extended_event_descriptor_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * An entry in the items field of a dvb_extended_event_descriptor.
+ */
+struct dvb_extended_event_item {
+ uint8_t item_description_length;
+ /* uint8_t item_description[] */
+ /* struct dvb_extended_event_item_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * The second part of a dvb_extended_event_item, following the variable length
+ * description field.
+ */
+struct dvb_extended_event_item_part2 {
+ uint8_t item_length;
+ /* uint8_t item[] */
+} __ucsi_packed;
+
+/**
+ * The second part of a dvb_extended_event_descriptor, following the variable
+ * length items field.
+ */
+struct dvb_extended_event_descriptor_part2 {
+ uint8_t text_length;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_extended_event_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_extended_event_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_extended_event_descriptor*
+ dvb_extended_event_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+ struct dvb_extended_event_descriptor * p =
+ (struct dvb_extended_event_descriptor *) d;
+ struct dvb_extended_event_descriptor_part2 *p2;
+
+ pos += sizeof(struct dvb_extended_event_descriptor) - 2;
+
+ if (pos > len)
+ return NULL;
+
+ pos += p->length_of_items;
+
+ if (pos > len)
+ return NULL;
+
+ p2 = (struct dvb_extended_event_descriptor_part2*) (buf+pos);
+
+ pos += sizeof(struct dvb_extended_event_descriptor_part2);
+
+ if (pos > len)
+ return NULL;
+
+ pos += p2->text_length;
+
+ if (pos != len)
+ return NULL;
+
+ return p;
+}
+
+/**
+ * Iterator for the items field of a dvb_extended_event_descriptor.
+ *
+ * @param d dvb_extended_event_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_extended_event_item.
+ */
+#define dvb_extended_event_descriptor_items_for_each(d, pos) \
+ for ((pos) = dvb_extended_event_descriptor_items_first(d); \
+ (pos); \
+ (pos) = dvb_extended_event_descriptor_items_next(d, pos))
+
+/**
+ * Accessor for the description field of a dvb_extended_event_item.
+ *
+ * @param d dvb_extended_event_item pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_extended_event_item_description(struct dvb_extended_event_item *d)
+{
+ return (uint8_t*) d + sizeof(struct dvb_extended_event_item);
+}
+
+/**
+ * Accessor for the second part of a dvb_extended_event_item.
+ *
+ * @param dvb_extended_event_item pointer.
+ * @return dvb_extended_event_item_part2 pointer.
+ */
+static inline struct dvb_extended_event_item_part2*
+ dvb_extended_event_item_part2(struct dvb_extended_event_item *d)
+{
+ return (struct dvb_extended_event_item_part2*)
+ ((uint8_t*) d + sizeof(struct dvb_extended_event_item) +
+ d->item_description_length);
+}
+
+/**
+ * Accessor for the item field of a dvb_extended_event_item_part2.
+ *
+ * @param d dvb_extended_event_item_part2 pointer.
+ * @return Pointer to the item field.
+ */
+static inline uint8_t*
+ dvb_extended_event_item_part2_item(struct dvb_extended_event_item_part2 *d)
+{
+ return (uint8_t*) d + sizeof(struct dvb_extended_event_item_part2);
+}
+
+/**
+ * Accessor for the second part of a dvb_extended_event_descriptor.
+ *
+ * @param d dvb_extended_event_descriptor pointer.
+ * @return dvb_extended_event_descriptor_part2 pointer.
+ */
+static inline struct dvb_extended_event_descriptor_part2*
+ dvb_extended_event_descriptor_part2(struct dvb_extended_event_descriptor *d)
+{
+ return (struct dvb_extended_event_descriptor_part2*)
+ ((uint8_t*) d + sizeof(struct dvb_extended_event_descriptor) +
+ d->length_of_items);
+}
+
+/**
+ * Accessor for the text field of an dvb_extended_event_descriptor_part2.
+ *
+ * @param d dvb_extended_event_descriptor_part2 pointer.
+ * @return Pointer to the text field.
+ */
+static inline uint8_t*
+ dvb_extended_event_descriptor_part2_text(struct dvb_extended_event_descriptor_part2 *d)
+{
+ return (uint8_t*)
+ ((uint8_t*) d + sizeof(struct dvb_extended_event_descriptor_part2));
+}
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_extended_event_item*
+ dvb_extended_event_descriptor_items_first(struct dvb_extended_event_descriptor *d)
+{
+ if (d->length_of_items == 0)
+ return NULL;
+
+ return (struct dvb_extended_event_item *)
+ ((uint8_t*) d + sizeof(struct dvb_extended_event_descriptor));
+}
+
+static inline struct dvb_extended_event_item*
+ dvb_extended_event_descriptor_items_next(struct dvb_extended_event_descriptor *d,
+ struct dvb_extended_event_item *pos)
+{
+ struct dvb_extended_event_item_part2* part2 =
+ dvb_extended_event_item_part2(pos);
+ uint8_t *end = (uint8_t*) d + sizeof(struct dvb_extended_event_descriptor) + d->length_of_items;
+ uint8_t *next = (uint8_t *) part2 +
+ sizeof(struct dvb_extended_event_item_part2) +
+ part2->item_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_extended_event_item *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/frequency_list_descriptor.h b/lib/libucsi/dvb/frequency_list_descriptor.h
new file mode 100644
index 0000000..4c18cec
--- /dev/null
+++ b/lib/libucsi/dvb/frequency_list_descriptor.h
@@ -0,0 +1,107 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_FREQUENCY_LIST_DESCRIPTOR
+#define _UCSI_DVB_FREQUENCY_LIST_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for coding_type.
+ */
+enum {
+ DVB_CODING_TYPE_SATELLITE = 0x01,
+ DVB_CODING_TYPE_CABLE = 0x02,
+ DVB_CODING_TYPE_TERRESTRIAL = 0x03,
+};
+
+/**
+ * dvb_frequency_list_descriptor structure.
+ */
+struct dvb_frequency_list_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 6; ,
+ uint8_t coding_type : 2; );
+ /* uint32_t centre_frequencies [] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_frequency_list_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return dvb_frequency_list_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_frequency_list_descriptor*
+ dvb_frequency_list_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ pos += sizeof(struct dvb_frequency_list_descriptor) - 2;
+
+ if ((len - pos) % 4)
+ return NULL;
+
+ while(pos < len) {
+ bswap32(buf+pos);
+ pos += 4;
+ }
+
+ return (struct dvb_frequency_list_descriptor*) d;
+}
+
+/**
+ * Accessor for the centre_frequencies field of a dvb_frequency_list_descriptor.
+ *
+ * @param d dvb_frequency_list_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint32_t *
+ dvb_frequency_list_descriptor_centre_frequencies(struct dvb_frequency_list_descriptor *d)
+{
+ return (uint32_t *) ((uint8_t *) d + sizeof(struct dvb_frequency_list_descriptor));
+}
+
+/**
+ * Determine the number of entries in the centre_frequencies field of a dvb_frequency_list_descriptor.
+ *
+ * @param d dvb_frequency_list_descriptor pointer.
+ * @return The number of entries.
+ */
+static inline int
+ dvb_frequency_list_descriptor_centre_frequencies_count(struct dvb_frequency_list_descriptor *d)
+{
+ return (d->d.len - 1) >> 2;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/int_section.c b/lib/libucsi/dvb/int_section.c
new file mode 100644
index 0000000..c2bb15f
--- /dev/null
+++ b/lib/libucsi/dvb/int_section.c
@@ -0,0 +1,79 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2005 Patrick Boettcher (pb@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/int_section.h>
+
+struct dvb_int_section * dvb_int_section_codec(struct section_ext *ext)
+{
+ uint8_t *buf = (uint8_t *) ext;
+ struct dvb_int_section *in = (struct dvb_int_section *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct dvb_int_section))
+ return NULL;
+
+ bswap32(buf+8);
+ bswap16(buf+12);
+ pos += 6;
+
+ if (len - pos < in->platform_descriptors_length)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, in->platform_descriptors_length))
+ return NULL;
+
+ pos += in->platform_descriptors_length;
+
+ while (pos < len) {
+ struct dvb_int_target *s2 = (struct dvb_int_target *) (buf + pos);
+ struct dvb_int_operational_loop *s3;
+
+ bswap16(buf + pos); /* target_descriptor_loop_length swap */
+
+ if (len - pos < s2->target_descriptors_length)
+ return NULL;
+
+ pos += sizeof(struct dvb_int_target);
+
+ if (verify_descriptors(buf + pos, s2->target_descriptors_length))
+ return NULL;
+
+ pos += s2->target_descriptors_length;
+
+ s3 = (struct dvb_int_operational_loop *) (buf + pos);
+
+ bswap16(buf + pos); /* operational_descriptor_loop_length swap */
+
+ if (len - pos < s3->operational_descriptors_length)
+ return NULL;
+
+ pos += sizeof(struct dvb_int_operational_loop);
+
+ if (verify_descriptors(buf + pos, s3->operational_descriptors_length))
+ return NULL;
+
+ pos += s3->operational_descriptors_length;
+ }
+
+ return (struct dvb_int_section *) ext;
+}
diff --git a/lib/libucsi/dvb/int_section.h b/lib/libucsi/dvb/int_section.h
new file mode 100644
index 0000000..932c0e8
--- /dev/null
+++ b/lib/libucsi/dvb/int_section.h
@@ -0,0 +1,245 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2005 Patrick Boettcher (pb@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef _UCSI_DVB_INT_SECTION_H
+#define _UCSI_DVB_INT_SECTION_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_int_section structure - IP/MAC notification section.
+ */
+struct dvb_int_section {
+ struct section_ext head;
+
+ EBIT2(uint32_t platform_id :24; ,
+ uint32_t processing_order : 8; );
+ EBIT2(uint16_t reserved2 : 4; ,
+ uint16_t platform_descriptors_length :12; );
+ /* struct descriptor platform_descriptors[] */
+ /* struct dvb_int_target target_loop[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the target_loop field of a dvb_int_section.
+ */
+struct dvb_int_target {
+ EBIT2(uint16_t reserved3 : 4; ,
+ uint16_t target_descriptors_length :12; );
+ /* struct descriptor target_descriptors[] */
+ /* struct dvb_int_operational_loop operational_loop */
+} __ucsi_packed;
+
+/**
+ * The operational_loop field in a dvb_int_target.
+ */
+struct dvb_int_operational_loop {
+ EBIT2(uint16_t reserved4 : 4; ,
+ uint16_t operational_descriptors_length :12; );
+ /* struct descriptor operational_descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_int_section.
+ *
+ * @param section Generic section_ext pointer.
+ * @return dvb_int_section pointer, or NULL on error.
+ */
+extern struct dvb_int_section * dvb_int_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the action_type field of an INT.
+ *
+ * @param intp INT pointer.
+ * @return The action_type.
+ */
+static inline uint8_t dvb_int_section_action_type(struct dvb_int_section *intp)
+{
+ return intp->head.table_id_ext >> 8;
+}
+
+/**
+ * Accessor for the platform_id_hash field of an INT.
+ *
+ * @param intp INT pointer.
+ * @return The platform_id_hash.
+ */
+static inline uint8_t dvb_int_section_platform_id_hash(struct dvb_int_section *intp)
+{
+ return intp->head.table_id_ext & 0xff;
+}
+
+/**
+ * Iterator for platform_descriptors field in a dvb_int_section.
+ *
+ * @param intp dvb_int_section pointer.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define dvb_int_section_platform_descriptors_for_each(intp, pos) \
+ for ((pos) = dvb_int_section_platform_descriptors_first(intp); \
+ (pos); \
+ (pos) = dvb_int_section_platform_descriptors_next(intp, pos))
+
+/**
+ * Iterator for the target_loop field in a dvb_int_section.
+ *
+ * @param intp dvb_int_section pointer.
+ * @param pos Variable holding a pointer to the current dvb_int_target.
+ */
+#define dvb_int_section_target_loop_for_each(intp,pos) \
+ for ((pos) = dvb_int_section_target_loop_first(intp); \
+ (pos); \
+ (pos) = dvb_int_section_target_loop_next(intp, pos))
+
+/**
+ * Iterator for the target_descriptors field in a dvb_int_target.
+ *
+ * @param target dvb_int_target pointer.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define dvb_int_target_target_descriptors_for_each(target, pos) \
+ for ((pos) = dvb_int_target_target_descriptors_first(target); \
+ (pos); \
+ (pos) = dvb_int_target_target_descriptors_next(target, pos))
+
+/**
+ * Accessor for the operational_loop field of a dvb_int_target.
+ *
+ * @param target dvb_int_target pointer.
+ * @return Pointer to a dvb_int_operational_loop.
+ */
+static inline struct dvb_int_operational_loop *
+ dvb_int_target_operational_loop(struct dvb_int_target *target)
+{
+ return (struct dvb_int_operational_loop *)
+ ((uint8_t *) target + sizeof(struct dvb_int_target) + target->target_descriptors_length);
+}
+
+/**
+ * Iterator for the operational_descriptors field in a dvb_int_operational_loop.
+ *
+ * @param oploop dvb_int_operational_loop pointer.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define dvb_int_operational_loop_operational_descriptors_for_each(oploop, pos) \
+ for ((pos) = dvb_int_operational_loop_operational_descriptors_first(oploop); \
+ (pos); \
+ (pos) = dvb_int_operational_loop_operational_descriptors_next(oploop, pos))
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ dvb_int_section_platform_descriptors_first(struct dvb_int_section *in)
+{
+ if (in->platform_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) in + sizeof(struct dvb_int_section));
+}
+
+static inline struct descriptor *
+ dvb_int_section_platform_descriptors_next(struct dvb_int_section *in,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) in + sizeof(struct dvb_int_section),
+ in->platform_descriptors_length,
+ pos);
+}
+
+static inline struct dvb_int_target *
+ dvb_int_section_target_loop_first(struct dvb_int_section *in)
+{
+ if (sizeof(struct dvb_int_section) + in->platform_descriptors_length >= (uint32_t) section_ext_length((struct section_ext *) in))
+ return NULL;
+
+ return (struct dvb_int_target *)
+ ((uint8_t *) in + sizeof(struct dvb_int_section) + in->platform_descriptors_length);
+}
+
+static inline struct dvb_int_target *
+ dvb_int_section_target_loop_next(struct dvb_int_section *in,
+ struct dvb_int_target *pos)
+{
+ struct dvb_int_operational_loop *ol = dvb_int_target_operational_loop(pos);
+ struct dvb_int_target *next =
+ (struct dvb_int_target *) ( (uint8_t *) pos +
+ sizeof(struct dvb_int_target) + pos->target_descriptors_length +
+ sizeof(struct dvb_int_operational_loop) + ol->operational_descriptors_length);
+ struct dvb_int_target *end =
+ (struct dvb_int_target *) ((uint8_t *) in + section_ext_length((struct section_ext *) in) );
+
+ if (next >= end)
+ return 0;
+ return next;
+}
+
+static inline struct descriptor *
+ dvb_int_target_target_descriptors_first(struct dvb_int_target *tl)
+{
+ if (tl->target_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) tl + sizeof(struct dvb_int_target));
+}
+
+static inline struct descriptor *
+ dvb_int_target_target_descriptors_next(struct dvb_int_target *tl,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) tl + sizeof(struct dvb_int_target),
+ tl->target_descriptors_length,
+ pos);
+}
+
+static inline struct descriptor *
+ dvb_int_operational_loop_operational_descriptors_first(struct dvb_int_operational_loop *ol)
+{
+ if (ol->operational_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) ol + sizeof(struct dvb_int_operational_loop));
+}
+
+static inline struct descriptor *
+ dvb_int_operational_loop_operational_descriptors_next(struct dvb_int_operational_loop *ol,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) ol + sizeof(struct dvb_int_operational_loop),
+ ol->operational_descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ip_mac_platform_name_descriptor.h b/lib/libucsi/dvb/ip_mac_platform_name_descriptor.h
new file mode 100644
index 0000000..c470e89
--- /dev/null
+++ b/lib/libucsi/dvb/ip_mac_platform_name_descriptor.h
@@ -0,0 +1,87 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR
+#define _UCSI_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_ip_platform_name_descriptor structure.
+ */
+struct dvb_ip_platform_name_descriptor {
+ struct descriptor d;
+
+ iso639lang_t language_code;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ip_platform_name_descriptor.
+ *
+ * @param d Pointer to a generic descriptor.
+ * @return dvb_ip_platform_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ip_platform_name_descriptor*
+ dvb_ip_platform_name_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_ip_platform_name_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_ip_platform_name_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of a dvb_ip_platform_name_descriptor.
+ *
+ * @param d dvb_ip_platform_name_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_ip_platform_name_descriptor_text(struct dvb_ip_platform_name_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_ip_platform_name_descriptor);
+}
+
+/**
+ * Determine the length of the text field of a dvb_ip_platform_name_descriptor.
+ *
+ * @param d dvb_ip_platform_name_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_ip_platform_name_descriptor_text_length(struct dvb_ip_platform_name_descriptor *d)
+{
+ return d->d.len - 3;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ip_mac_platform_provider_name_descriptor.h b/lib/libucsi/dvb/ip_mac_platform_provider_name_descriptor.h
new file mode 100644
index 0000000..ba95b8f
--- /dev/null
+++ b/lib/libucsi/dvb/ip_mac_platform_provider_name_descriptor.h
@@ -0,0 +1,87 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR
+#define _UCSI_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_ip_platform_provider_name_descriptor structure.
+ */
+struct dvb_ip_platform_provider_name_descriptor {
+ struct descriptor d;
+
+ iso639lang_t language_code;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ip_platform_provider_name_descriptor.
+ *
+ * @param d Pointer to a generic descriptor.
+ * @return dvb_ip_platform_provider_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ip_platform_provider_name_descriptor*
+ dvb_ip_platform_provider_name_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_ip_platform_provider_name_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_ip_platform_provider_name_descriptor*) d;
+}
+
+/**
+ * Accessor for the text field of a dvb_ip_platform_provider_name_descriptor.
+ *
+ * @param d dvb_ip_platform_provider_name_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_ip_platform_provider_name_descriptor_text(struct dvb_ip_platform_provider_name_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_ip_platform_provider_name_descriptor);
+}
+
+/**
+ * Determine the length of the text field of a dvb_ip_platform_provider_name_descriptor.
+ *
+ * @param d dvb_ip_platform_provider_name_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_ip_platform_provider_name_descriptor_text_length(struct dvb_ip_platform_provider_name_descriptor *d)
+{
+ return d->d.len - 3;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/ip_mac_stream_location_descriptor.h b/lib/libucsi/dvb/ip_mac_stream_location_descriptor.h
new file mode 100644
index 0000000..36216d6
--- /dev/null
+++ b/lib/libucsi/dvb/ip_mac_stream_location_descriptor.h
@@ -0,0 +1,73 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_IP_MAC_STREAM_LOCATION_DESCRIPTOR
+#define _UCSI_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_ip_mac_stream_location_descriptor structure.
+ */
+struct dvb_ip_mac_stream_location_descriptor {
+ struct descriptor d;
+
+ uint16_t network_id;
+ uint16_t original_network_id;
+ uint16_t transport_stream_id;
+ uint16_t service_id;
+ uint8_t component_tag;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_ip_mac_stream_location_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_ip_mac_stream_location_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_ip_mac_stream_location_descriptor*
+ dvb_ip_mac_stream_location_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+
+ if (d->len != (sizeof(struct dvb_ip_mac_stream_location_descriptor) - 2))
+ return NULL;
+
+ bswap16(buf);
+ bswap16(buf+2);
+ bswap16(buf+4);
+ bswap16(buf+6);
+
+ return (struct dvb_ip_mac_stream_location_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/linkage_descriptor.h b/lib/libucsi/dvb/linkage_descriptor.h
new file mode 100644
index 0000000..d2be789
--- /dev/null
+++ b/lib/libucsi/dvb/linkage_descriptor.h
@@ -0,0 +1,480 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_LINKAGE_DESCRIPTOR
+#define _UCSI_DVB_LINKAGE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * Possible values for linkage_type.
+ */
+enum {
+ DVB_LINKAGE_TYPE_INFORMATION = 0x01,
+ DVB_LINKAGE_TYPE_EPG = 0x02,
+ DVB_LINKAGE_TYPE_CA_REPLACEMENT = 0x03,
+ DVB_LINKAGE_TYPE_TS_WITH_BAT_NIT = 0x04,
+ DVB_LINKAGE_TYPE_SERVICE_REPLACMENT = 0x05,
+ DVB_LINKAGE_TYPE_DATA_BCAST = 0x06,
+ DVB_LINKAGE_TYPE_RCS_MAP = 0x07,
+ DVB_LINKAGE_TYPE_MOBILE_HANDOVER = 0x08,
+ DVB_LINKAGE_TYPE_SOFTWARE_UPDATE = 0x09,
+ DVB_LINKAGE_TYPE_TS_WITH_SSU_BAT_NIT = 0x0a,
+ DVB_LINKAGE_TYPE_IP_MAC_NOTIFICATION = 0x0b,
+ DVB_LINKAGE_TYPE_TS_WITH_INT_BAT_NIT = 0x0c,
+};
+
+/**
+ * Possible values for hand_over_type.
+ */
+enum {
+ DVB_HAND_OVER_TYPE_IDENTICAL_NEIGHBOURING_COUNTRY = 0x01,
+ DVB_HAND_OVER_TYPE_LOCAL_VARIATION = 0x02,
+ DVB_HAND_OVER_TYPE_ASSOCIATED_SERVICE = 0x03,
+};
+
+/**
+ * Possible values for origin_type.
+ */
+enum {
+ DVB_ORIGIN_TYPE_NIT = 0x00,
+ DVB_ORIGIN_TYPE_SDT = 0x01,
+};
+
+/**
+ * dvb_linkage_descriptor structure.
+ */
+struct dvb_linkage_descriptor {
+ struct descriptor d;
+
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ uint16_t service_id;
+ uint8_t linkage_type;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Data for a linkage_type of 0x08.
+ */
+struct dvb_linkage_data_08 {
+ EBIT3(uint8_t hand_over_type : 4; ,
+ uint8_t reserved : 3; ,
+ uint8_t origin_type : 1; );
+ /* uint16_t network_id if hand_over_type == 1,2,3 */
+ /* uint16_t initial_service_id if origin_type = 0 */
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Data for an linkage_type of 0x0b (IP/MAC Notification Table).
+ */
+struct dvb_linkage_data_0b {
+ uint8_t platform_id_data_length;
+ /* struct platform_id ids[] */
+} __ucsi_packed;
+
+/**
+ * Entries in the ids field of a dvb_linkage_data_0b.
+ */
+struct dvb_platform_id {
+ EBIT2(uint32_t platform_id : 24; ,
+ uint8_t platform_name_loop_length : 8; );
+ /* struct platform_name names[] */
+} __ucsi_packed;
+
+/**
+ * Entries in the names field of a dvb_platform_id.
+ */
+struct dvb_platform_name {
+ iso639lang_t language_code;
+ uint8_t platform_name_length;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Data for a linkage_type of 0x0c (IP/MAC Notification Table).
+ */
+struct dvb_linkage_data_0c {
+ uint8_t table_type;
+ /* uint16_t bouquet_id if table_type == 0x02 */
+} __ucsi_packed;
+
+
+/**
+ * Process a dvb_linkage_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_linkage_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_linkage_descriptor*
+ dvb_linkage_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+ struct dvb_linkage_descriptor *p =
+ (struct dvb_linkage_descriptor*) d;
+
+ if (len < (sizeof(struct dvb_linkage_descriptor) - 2))
+ return NULL;
+
+ bswap16(buf);
+ bswap16(buf+2);
+ bswap16(buf+4);
+
+ pos += sizeof(struct dvb_linkage_descriptor) - 2;
+
+ if (p->linkage_type == 0x08) {
+ struct dvb_linkage_data_08 *d08;
+
+ if ((len - pos) < sizeof(struct dvb_linkage_data_08))
+ return NULL;
+ d08 = (struct dvb_linkage_data_08 *) (buf+pos);
+ pos += sizeof(struct dvb_linkage_data_08);
+
+ switch(d08->hand_over_type) {
+ case 1:
+ case 2:
+ case 3:
+ if ((len - pos) < 2)
+ return NULL;
+ bswap16(buf+pos);
+ pos += 2;
+ break;
+ }
+ if (d08->origin_type == 0) {
+ if ((len - pos) < 2)
+ return NULL;
+ bswap16(buf+pos);
+ pos+=2;
+ }
+
+ } else if (p->linkage_type == 0x0b) {
+ uint32_t pos2=0;
+ struct dvb_linkage_data_0b *l_0b = (struct dvb_linkage_data_0b *) (buf + pos);
+
+ if ((len - pos) < sizeof(struct dvb_linkage_data_0b))
+ return NULL;
+
+ pos += sizeof(struct dvb_linkage_data_0b);
+ if ((len - pos) < l_0b->platform_id_data_length)
+ return NULL;
+
+ while (pos2 < l_0b->platform_id_data_length) {
+ bswap32(buf + pos + pos2);
+
+ struct dvb_platform_id *p_id = (struct dvb_platform_id *) (buf + pos + pos2);
+ if ((len - pos - pos2) < p_id->platform_name_loop_length)
+ return NULL;
+
+ pos2 += sizeof(struct dvb_platform_id) + p_id->platform_name_loop_length;
+ }
+
+ pos += pos2;
+ } else if (p->linkage_type == 0x0c) {
+ struct dvb_linkage_data_0c *l_0c = (struct dvb_linkage_data_0c *) (buf + pos);
+
+ if ((len - pos) < sizeof(struct dvb_linkage_data_0c))
+ return NULL;
+ pos += sizeof(struct dvb_linkage_data_0c);
+
+ if (l_0c->table_type == 0x02) {
+ if ((len - pos) < 2)
+ return NULL;
+ bswap16(buf+pos);
+ }
+ }
+
+ return (struct dvb_linkage_descriptor*) d;
+}
+
+/**
+ * Accessor for the data field of a dvb_linkage_descriptor.
+ *
+ * @param d dvb_linkage_descriptor pointer.
+ * @return Pointer to the data field.
+ */
+static inline uint8_t *
+ dvb_linkage_descriptor_data(struct dvb_linkage_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_linkage_descriptor);
+}
+
+/**
+ * Determine the length of the data field of a dvb_linkage_descriptor.
+ *
+ * @param d dvb_linkage_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_linkage_descriptor_data_length(struct dvb_linkage_descriptor *d)
+{
+ return d->d.len - 7;
+}
+
+/**
+ * Accessor for a dvb_linkage_data_08 pointer.
+ *
+ * @param d dvb_linkage_descriptor pointer.
+ * @return Pointer to the data field.
+ */
+static inline struct dvb_linkage_data_08 *
+ dvb_linkage_data_08(struct dvb_linkage_descriptor *d)
+{
+ if (d->linkage_type != 0x08)
+ return NULL;
+ return (struct dvb_linkage_data_08 *) dvb_linkage_descriptor_data(d);
+}
+
+/**
+ * Accessor for the network_id field of a dvb_linkage_data_08.
+ *
+ * @param d dvb_linkage_descriptor pointer
+ * @param d08 dvb_linkage_data_08 pointer.
+ * @return network_id, or -1 if not present
+ */
+static inline int
+ dvb_linkage_data_08_network_id(struct dvb_linkage_descriptor *d, struct dvb_linkage_data_08 *d08)
+{
+ if (d->linkage_type != 0x08)
+ return -1;
+
+ switch(d08->hand_over_type) {
+ case 1:
+ case 2:
+ case 3:
+ return *((uint16_t*) ((uint8_t*) d08 + sizeof(struct dvb_linkage_data_08)));
+ }
+
+ return -1;
+}
+
+/**
+ * Accessor for the initial_service_id field of a dvb_linkage_data_08.
+ *
+ * @param d dvb_linkage_descriptor pointer
+ * @param d08 dvb_linkage_data_08 pointer.
+ * @return initial_service_id, or -1 if not present
+ */
+static inline int
+ dvb_linkage_data_08_initial_service_id(struct dvb_linkage_descriptor *d, struct dvb_linkage_data_08 *d08)
+{
+ uint8_t *pos;
+
+ if (d->linkage_type != 0x08)
+ return -1;
+ if (d08->origin_type != 0)
+ return -1;
+
+ pos = ((uint8_t*) d08) + sizeof(struct dvb_linkage_data_08);
+ switch(d08->hand_over_type) {
+ case 1:
+ case 2:
+ case 3:
+ pos +=2;
+ break;
+ }
+
+ return *((uint16_t*) pos);
+}
+
+/**
+ * Accessor for the data field of a dvb_linkage_data_08.
+ *
+ * @param d dvb_linkage_descriptor pointer
+ * @param d08 dvb_linkage_data_08 pointer.
+ * @param length Pointer to int destination for data length.
+ * @return Pointer to the data field, or NULL if invalid
+ */
+static inline uint8_t *
+ dvb_linkage_data_08_data(struct dvb_linkage_descriptor *d, struct dvb_linkage_data_08 *d08, int *length)
+{
+ uint8_t *pos;
+ int used = 0;
+
+ if (d->linkage_type != 0x08) {
+ *length = 0;
+ return NULL;
+ }
+
+ pos = ((uint8_t*) d08) + sizeof(struct dvb_linkage_data_08);
+ switch(d08->hand_over_type) {
+ case 1:
+ case 2:
+ case 3:
+ pos += 2;
+ used += 2;
+ break;
+ }
+ if (d08->origin_type == 0) {
+ pos+=2;
+ used+=2;
+ }
+
+ *length = dvb_linkage_descriptor_data_length(d) - (sizeof(struct dvb_linkage_data_08) + used);
+ return pos;
+}
+
+/**
+ * Accessor for a dvb_linkage_data_0b pointer.
+ *
+ * @param d dvb_linkage_descriptor pointer.
+ * @return Pointer to the data field.
+ */
+static inline struct dvb_linkage_data_0b *
+ dvb_linkage_data_0b(struct dvb_linkage_descriptor *d)
+{
+ if (d->linkage_type != 0x0b)
+ return NULL;
+ return (struct dvb_linkage_data_0b *) dvb_linkage_descriptor_data(d);
+}
+
+/**
+ * Iterator for the platform_id field of a dvb_linkage_data_0b.
+ *
+ * @param linkage dvb_linkage_data_0b pointer.
+ * @param pos Variable containing a pointer to the current dvb_platform_id.
+ */
+#define dvb_linkage_data_0b_platform_id_for_each(linkage, pos) \
+ for ((pos) = dvb_platform_id_first(linkage); \
+ (pos); \
+ (pos) = dvb_platform_id_next(linkage, pos))
+
+/**
+ * Iterator for the platform_name field of a dvb_platform_id.
+ *
+ * @param platid dvb_platform_id pointer.
+ * @param pos Variable containing a pointer to the current dvb_platform_name.
+ */
+#define dvb_platform_id_platform_name_for_each(platid, pos) \
+ for ((pos) = dvb_platform_name_first(platid); \
+ (pos); \
+ (pos) = dvb_platform_name_next(platid, pos))
+
+/**
+ * Accessor for the text field of a dvb_platform_name.
+ *
+ * @param p dvb_platform_name pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_platform_name_text(struct dvb_platform_name *p)
+{
+ return (uint8_t *) p + sizeof(struct dvb_platform_name);
+}
+
+/**
+ * Accessor for a dvb_linkage_data_0c pointer.
+ *
+ * @param d dvb_linkage_descriptor pointer.
+ * @return Pointer to the data field.
+ */
+static inline struct dvb_linkage_data_0c *
+ dvb_linkage_data_0c(struct dvb_linkage_descriptor *d)
+{
+ if (d->linkage_type != 0x0c)
+ return NULL;
+ return (struct dvb_linkage_data_0c *) dvb_linkage_descriptor_data(d);
+}
+
+/**
+ * Accessor for the bouquet_id field of a dvb_linkage_data_0c if table_id == 0x02.
+ *
+ * @param l_0c dvb_linkage_data_0c pointer.
+ * @return The bouquet field, or -1 on error.
+ */
+static inline int
+ dvb_linkage_data_0c_bouquet_id(struct dvb_linkage_data_0c *l_0c)
+{
+ if (l_0c->table_type != 0x02)
+ return -1;
+
+ return *((uint16_t *) ((uint8_t*) l_0c + 1));
+}
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_platform_id *
+ dvb_platform_id_first(struct dvb_linkage_data_0b *d)
+{
+ if (d->platform_id_data_length == 0)
+ return NULL;
+
+ return (struct dvb_platform_id *) ((uint8_t *) d + sizeof(struct dvb_linkage_data_0b));
+}
+
+static inline struct dvb_platform_id *
+ dvb_platform_id_next(struct dvb_linkage_data_0b *d,
+ struct dvb_platform_id *pos)
+{
+ uint8_t *end = (uint8_t *) d + d->platform_id_data_length;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_platform_id) +
+ pos->platform_name_loop_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_platform_id *) next;
+}
+
+static inline struct dvb_platform_name *
+ dvb_platform_name_first(struct dvb_platform_id *p)
+{
+ if (p->platform_name_loop_length == 0)
+ return NULL;
+
+ return (struct dvb_platform_name *) ((uint8_t *) p + sizeof(struct dvb_platform_id));
+}
+
+static inline struct dvb_platform_name *
+ dvb_platform_name_next(struct dvb_platform_id *p,
+ struct dvb_platform_name *pos)
+{
+ uint8_t *end = (uint8_t *) p + p->platform_name_loop_length;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_platform_name) +
+ pos->platform_name_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_platform_name *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/local_time_offset_descriptor.h b/lib/libucsi/dvb/local_time_offset_descriptor.h
new file mode 100644
index 0000000..d0eebb3
--- /dev/null
+++ b/lib/libucsi/dvb/local_time_offset_descriptor.h
@@ -0,0 +1,127 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_LOCAL_TIME_OFFSET_DESCRIPTOR
+#define _UCSI_DVB_LOCAL_TIME_OFFSET_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+#include <libucsi/dvb/types.h>
+
+/**
+ * dvb_local_time_offset_descriptor parameter.
+ */
+struct dvb_local_time_offset_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_local_time_offset offsets[] */
+} __ucsi_packed;
+
+/**
+ * Entry in the offsets field of dvb_local_time_offset_descriptor.
+ */
+struct dvb_local_time_offset {
+ iso639country_t country_code;
+ EBIT3(uint8_t country_region_id : 6; ,
+ uint8_t reserved : 1; ,
+ uint8_t local_time_offset_polarity : 1; );
+ dvbhhmm_t local_time_offset;
+ dvbdate_t time_of_change;
+ dvbhhmm_t next_time_offset;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_local_time_offset_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_local_time_offset_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_local_time_offset_descriptor*
+ dvb_local_time_offset_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+ uint32_t pos = 0;
+
+ if (len % sizeof(struct dvb_local_time_offset))
+ return NULL;
+
+ while(pos < len) {
+ pos += sizeof(struct dvb_local_time_offset);
+ }
+
+ return (struct dvb_local_time_offset_descriptor*) d;
+}
+
+/**
+ * Iterator for the offsets field of a dvb_local_time_offset_descriptor.
+ *
+ * @param d dvb_local_time_offset_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_local_time_offset.
+ */
+#define dvb_local_time_offset_descriptor_offsets_for_each(d, pos) \
+ for ((pos) = dvb_local_time_offset_descriptor_offsets_first(d); \
+ (pos); \
+ (pos) = dvb_local_time_offset_descriptor_offsets_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_local_time_offset*
+ dvb_local_time_offset_descriptor_offsets_first(struct dvb_local_time_offset_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_local_time_offset *)
+ ((uint8_t*) d + sizeof(struct dvb_local_time_offset_descriptor));
+}
+
+static inline struct dvb_local_time_offset*
+ dvb_local_time_offset_descriptor_offsets_next(struct dvb_local_time_offset_descriptor *d,
+ struct dvb_local_time_offset *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_local_time_offset);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_local_time_offset *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/mhp_data_broadcast_id_descriptor.h b/lib/libucsi/dvb/mhp_data_broadcast_id_descriptor.h
new file mode 100644
index 0000000..d79b48c
--- /dev/null
+++ b/lib/libucsi/dvb/mhp_data_broadcast_id_descriptor.h
@@ -0,0 +1,110 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_MHP_DATA_BROADCAST_ID_DESCRIPTOR
+#define _UCSI_DVB_MHP_DATA_BROADCAST_ID_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef _UCSI_DVB_DATA_BROADCAST_ID_DESCRIPTOR
+#error Must include dvb/data_broadcast_id_descriptor.h first
+#endif
+
+/**
+ * Broadcast IDs for MHP.
+ */
+enum {
+ DVB_BROADCAST_ID_MHP_OBJECT_CAROUSEL = 0x00f0,
+ DVB_BROADCAST_ID_MHP_MPE = 0x00f1,
+};
+
+/**
+ * dvb_mhp_data_broadcast_id_descriptor structure.
+ */
+struct dvb_mhp_data_broadcast_id_descriptor {
+ struct dvb_data_broadcast_id_descriptor d;
+ /* uint16_t application_type[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_mhp_data_broadcast_id_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_mhp_data_broadcast_id_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_mhp_data_broadcast_id_descriptor*
+ dvb_mhp_data_broadcast_id_descriptor_codec(struct dvb_data_broadcast_id_descriptor* d)
+{
+ uint8_t * buf;
+ int len;
+ int pos = 0;
+ struct dvb_mhp_data_broadcast_id_descriptor *res =
+ (struct dvb_mhp_data_broadcast_id_descriptor *) d;
+
+ if ((res->d.data_broadcast_id < 0xf0) || (res->d.data_broadcast_id > 0xfe))
+ return NULL;
+
+ buf = dvb_data_broadcast_id_descriptor_id_selector_byte(d);
+ len = dvb_data_broadcast_id_descriptor_id_selector_byte_length(d);
+
+ if (len % 2)
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ pos+=2;
+ }
+
+ return res;
+}
+
+/**
+ * Accessor for the application_type field of a dvb_mhp_data_broadcast_id_descriptor.
+ *
+ * @param d dvb_mhp_data_broadcast_id_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint16_t *
+ dvb_mhp_data_broadcast_id_descriptor_id_application_type(struct dvb_mhp_data_broadcast_id_descriptor *d)
+{
+ return (uint16_t *) dvb_data_broadcast_id_descriptor_id_selector_byte((struct dvb_data_broadcast_id_descriptor*) d);
+}
+
+/**
+ * Determine the number of entries in the application_type field of a dvb_mhp_data_broadcast_id_descriptor.
+ *
+ * @param d dvb_data_broadcast_id_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_mhp_data_broadcast_id_descriptor_id_application_type_count(struct dvb_mhp_data_broadcast_id_descriptor *d)
+{
+ return dvb_data_broadcast_id_descriptor_id_selector_byte_length((struct dvb_data_broadcast_id_descriptor*) d) >> 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/mosaic_descriptor.h b/lib/libucsi/dvb/mosaic_descriptor.h
new file mode 100644
index 0000000..6da1e95
--- /dev/null
+++ b/lib/libucsi/dvb/mosaic_descriptor.h
@@ -0,0 +1,324 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_MOSAIC_DESCRIPTOR
+#define _UCSI_DVB_MOSAIC_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_mosaic_descriptor structure.
+ */
+struct dvb_mosaic_descriptor {
+ struct descriptor d;
+
+ EBIT4(uint8_t mosaic_entry_point : 1; ,
+ uint8_t number_of_horiz_elementary_cells: 3; ,
+ uint8_t reserved : 1; ,
+ uint8_t number_of_vert_elementary_cells : 3; );
+ /* struct dvb_mosaic_info infos[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the infos field of a dvb_mosaic_descriptor.
+ */
+struct dvb_mosaic_info {
+ EBIT3(uint16_t logical_cell_id : 6; ,
+ uint16_t reserved : 7; ,
+ uint16_t logical_cell_presentation_info : 3; );
+ uint8_t elementary_cell_field_length;
+ /* struct dvb_mosaic_elementary_cell_field fields[] */
+ /* struct dvb_mosaic_info_part2 part2 */
+ /* struct dvb_mosaic_linkage linkage */
+} __ucsi_packed;
+
+/**
+ * An entry in the fields field of a dvb_mosaic_info.
+ */
+struct dvb_mosaic_elementary_cell_field {
+ EBIT2(uint8_t reserved : 2; ,
+ uint8_t elementary_cell_id : 6; );
+} __ucsi_packed;
+
+/**
+ * Part2 of dvb_mosaic_info, following the variable length fields field.
+ */
+struct dvb_mosaic_info_part2 {
+ uint8_t cell_linkage_info;
+} __ucsi_packed;
+
+struct dvb_mosaic_linkage_01 {
+ uint16_t bouquet_id;
+} __ucsi_packed;
+
+struct dvb_mosaic_linkage_02 {
+ uint16_t original_network_id;
+ uint16_t transport_stream_id;
+ uint16_t service_id;
+} __ucsi_packed;
+
+struct dvb_mosaic_linkage_03 {
+ uint16_t original_network_id;
+ uint16_t transport_stream_id;
+ uint16_t service_id;
+} __ucsi_packed;
+
+struct dvb_mosaic_linkage_04 {
+ uint16_t original_network_id;
+ uint16_t transport_stream_id;
+ uint16_t service_id;
+ uint16_t event_id;
+} __ucsi_packed;
+
+/**
+ * Structure describing the linkage field of a dvb_mosaic_info
+ */
+struct dvb_mosaic_linkage {
+ union {
+ struct dvb_mosaic_linkage_01 linkage_01;
+ struct dvb_mosaic_linkage_02 linkage_02;
+ struct dvb_mosaic_linkage_03 linkage_03;
+ struct dvb_mosaic_linkage_04 linkage_04;
+ } u;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_mosaic_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ */
+static inline struct dvb_mosaic_descriptor*
+ dvb_mosaic_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+ struct dvb_mosaic_descriptor * p =
+ (struct dvb_mosaic_descriptor *) d;
+
+ pos += (sizeof(struct dvb_mosaic_descriptor) - 2);
+
+ if (pos > len)
+ return NULL;
+
+ while(pos < len) {
+ struct dvb_mosaic_info *e =
+ (struct dvb_mosaic_info*) (buf+pos);
+ struct dvb_mosaic_info_part2 *e2;
+ struct dvb_mosaic_linkage *linkage;
+
+ if ((pos + sizeof(struct dvb_mosaic_info)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+
+ pos += sizeof(struct dvb_mosaic_info) +
+ e->elementary_cell_field_length;
+
+ if (pos > len)
+ return NULL;
+
+ e2 = (struct dvb_mosaic_info_part2*) (buf+pos);
+
+ pos += sizeof(struct dvb_mosaic_info_part2);
+
+ if (pos > len)
+ return NULL;
+
+ linkage = (struct dvb_mosaic_linkage*) (buf+pos);
+
+ switch(e2->cell_linkage_info) {
+ case 0x01:
+ if ((pos + sizeof(struct dvb_mosaic_linkage_01)) > len)
+ return NULL;
+ bswap16(buf+pos);
+ pos += sizeof(struct dvb_mosaic_linkage_01);
+ break;
+
+ case 0x02:
+ if ((pos + sizeof(struct dvb_mosaic_linkage_02)) > len)
+ return NULL;
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap16(buf+pos+4);
+ pos += sizeof(struct dvb_mosaic_linkage_02);
+ break;
+
+ case 0x03:
+ if ((pos + sizeof(struct dvb_mosaic_linkage_03)) > len)
+ return NULL;
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap16(buf+pos+4);
+ pos += sizeof(struct dvb_mosaic_linkage_03);
+ break;
+
+ case 0x04:
+ if ((pos + sizeof(struct dvb_mosaic_linkage_04)) > len)
+ return NULL;
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap16(buf+pos+4);
+ bswap16(buf+pos+6);
+ pos += sizeof(struct dvb_mosaic_linkage_04);
+ break;
+ }
+ }
+
+ return p;
+}
+
+/**
+ * Iterator over the infos field of a dvb_mosaic_descriptor.
+ *
+ * @param d dvb_mosaic_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_mosaic_info.
+ */
+#define dvb_mosaic_descriptor_infos_for_each(d, pos) \
+ for ((pos) = dvb_mosaic_descriptor_infos_first(d); \
+ (pos); \
+ (pos) = dvb_mosaic_descriptor_infos_next(d, pos))
+
+/**
+ * Iterator over the fields field of a dvb_mosaic_info.
+ *
+ * @param info dvb_mosaic_info pointer.
+ * @param pos Variable containing a pointer to the current dvb_mosaic_elementary_cell_field.
+ */
+#define dvb_mosaic_info_fields_for_each(info, pos) \
+ for ((pos) = dvb_mosaic_info_fields_first(info); \
+ (pos); \
+ (pos) = dvb_mosaic_info_fields_next(info, pos))
+
+/**
+ * Accessor for the second part of the dvb_mosaic_info structure.
+ *
+ * @param entry dvb_mosaic_info pointer.
+ * @return dvb_mosaic_info_part2 pointer.
+ */
+static inline struct dvb_mosaic_info_part2*
+ dvb_mosaic_info_part2(struct dvb_mosaic_info* entry)
+{
+ return (struct dvb_mosaic_info_part2*)
+ ((uint8_t*) entry + sizeof(struct dvb_mosaic_info) +
+ entry->elementary_cell_field_length);
+}
+
+/**
+ * Accessor for the linkage field a dvb_mosaic_info structure.
+ *
+ * @param entry dvb_mosaic_info_part2 pointer.
+ * @return dvb_mosaic_linkage pointer, or NULL on error.
+ */
+static inline struct dvb_mosaic_linkage*
+ dvb_mosaic_linkage(struct dvb_mosaic_info_part2* entry)
+{
+ if ((entry->cell_linkage_info != 0x01) &&
+ (entry->cell_linkage_info != 0x02) &&
+ (entry->cell_linkage_info != 0x03) &&
+ (entry->cell_linkage_info != 0x04))
+ return NULL;
+
+ return (struct dvb_mosaic_linkage*)
+ ((uint8_t*) entry + sizeof(struct dvb_mosaic_info_part2));
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_mosaic_info*
+ dvb_mosaic_descriptor_infos_first(struct dvb_mosaic_descriptor *d)
+{
+ if (d->d.len == 1)
+ return NULL;
+
+ return (struct dvb_mosaic_info *)
+ ((uint8_t*) d + sizeof(struct dvb_mosaic_descriptor));
+}
+
+static inline struct dvb_mosaic_info*
+ dvb_mosaic_descriptor_infos_next(struct dvb_mosaic_descriptor *d,
+ struct dvb_mosaic_info *pos)
+{
+ struct dvb_mosaic_info_part2* part2 = dvb_mosaic_info_part2(pos);
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_mosaic_info) +
+ pos->elementary_cell_field_length +
+ sizeof(struct dvb_mosaic_info_part2);
+
+ if (part2->cell_linkage_info == 0x01)
+ next += sizeof(struct dvb_mosaic_linkage_01);
+ else if (part2->cell_linkage_info == 0x02)
+ next += sizeof(struct dvb_mosaic_linkage_02);
+ else if (part2->cell_linkage_info == 0x03)
+ next += sizeof(struct dvb_mosaic_linkage_03);
+ else if (part2->cell_linkage_info == 0x04)
+ next += sizeof(struct dvb_mosaic_linkage_04);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_mosaic_info *) next;
+}
+
+static inline struct dvb_mosaic_elementary_cell_field*
+ dvb_mosaic_info_fields_first(struct dvb_mosaic_info *d)
+{
+ if (d->elementary_cell_field_length == 0)
+ return NULL;
+
+ return (struct dvb_mosaic_elementary_cell_field*)
+ ((uint8_t*) d + sizeof(struct dvb_mosaic_info));
+}
+
+static inline struct dvb_mosaic_elementary_cell_field*
+ dvb_mosaic_info_fields_next(struct dvb_mosaic_info *d,
+ struct dvb_mosaic_elementary_cell_field* pos)
+{
+ uint8_t *end = (uint8_t*) d + sizeof(struct dvb_mosaic_info) +
+ d->elementary_cell_field_length;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_mosaic_elementary_cell_field);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_mosaic_elementary_cell_field *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/multilingual_bouquet_name_descriptor.h b/lib/libucsi/dvb/multilingual_bouquet_name_descriptor.h
new file mode 100644
index 0000000..0d8deb1
--- /dev/null
+++ b/lib/libucsi/dvb/multilingual_bouquet_name_descriptor.h
@@ -0,0 +1,145 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_MULTILINGUAL_BOUQUET_NAME_DESCRIPTOR
+#define _UCSI_DVB_MULTILINGUAL_BOUQUET_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_multilingual_bouquet_name_descriptor structure.
+ */
+struct dvb_multilingual_bouquet_name_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_multilingual_bouquet_name names[]*/
+} __ucsi_packed;
+
+/**
+ * An entry in the names field of a dvb_multilingual_bouquet_name_descriptor.
+ */
+struct dvb_multilingual_bouquet_name {
+ iso639lang_t language_code;
+ uint8_t bouquet_name_length;
+ /* uint8_t name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_multilingual_bouquet_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_multilingual_bouquet_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_multilingual_bouquet_name_descriptor*
+ dvb_multilingual_bouquet_name_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_multilingual_bouquet_name *e =
+ (struct dvb_multilingual_bouquet_name*) (buf+pos);
+
+ pos += sizeof(struct dvb_multilingual_bouquet_name);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e->bouquet_name_length;
+
+ if (pos > len)
+ return NULL;
+ }
+
+ return (struct dvb_multilingual_bouquet_name_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the names field of a dvb_multilingual_bouquet_name_descriptor.
+ *
+ * @param d dvb_multilingual_bouquet_name_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_multilingual_bouquet_name.
+ */
+#define dvb_multilingual_bouquet_name_descriptor_names_for_each(d, pos) \
+ for ((pos) = dvb_multilingual_bouquet_name_descriptor_names_first(d); \
+ (pos); \
+ (pos) = dvb_multilingual_bouquet_name_descriptor_names_next(d, pos))
+
+/**
+ * Accessor for the name field of a dvb_multilingual_bouquet_name.
+ *
+ * @param e dvb_multilingual_bouquet_name pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_multilingual_bouquet_name_name(struct dvb_multilingual_bouquet_name *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_multilingual_bouquet_name);
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_multilingual_bouquet_name*
+ dvb_multilingual_bouquet_name_descriptor_names_first(struct dvb_multilingual_bouquet_name_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_multilingual_bouquet_name *)
+ ((uint8_t*) d + sizeof(struct dvb_multilingual_bouquet_name_descriptor));
+}
+
+static inline struct dvb_multilingual_bouquet_name*
+ dvb_multilingual_bouquet_name_descriptor_names_next(struct dvb_multilingual_bouquet_name_descriptor *d,
+ struct dvb_multilingual_bouquet_name *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_multilingual_bouquet_name) +
+ pos->bouquet_name_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_multilingual_bouquet_name *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/multilingual_component_descriptor.h b/lib/libucsi/dvb/multilingual_component_descriptor.h
new file mode 100644
index 0000000..ab156af
--- /dev/null
+++ b/lib/libucsi/dvb/multilingual_component_descriptor.h
@@ -0,0 +1,149 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_MULTILINGUAL_COMPONENT_DESCRIPTOR
+#define _UCSI_DVB_MULTILINGUAL_COMPONENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_multilingual_component_descriptor structure.
+ */
+struct dvb_multilingual_component_descriptor {
+ struct descriptor d;
+
+ uint8_t component_tag;
+ /* struct dvb_multilingual_component components[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the components field of a dvb_multilingual_component_descriptor.
+ */
+struct dvb_multilingual_component {
+ iso639lang_t language_code;
+ uint8_t text_description_length;
+ /* uint8_t text_char[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_multilingual_component_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_multilingual_component_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_multilingual_component_descriptor*
+ dvb_multilingual_component_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = sizeof(struct dvb_multilingual_component_descriptor) - 2;
+ uint32_t len = d->len;
+
+ if (pos > len)
+ return NULL;
+
+ while(pos < len) {
+ struct dvb_multilingual_component *e =
+ (struct dvb_multilingual_component*) (buf+pos);
+
+ pos += sizeof(struct dvb_multilingual_component);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e->text_description_length;
+
+ if (pos > len)
+ return NULL;
+ }
+
+ return (struct dvb_multilingual_component_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the components field of a dvb_multilingual_component_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_multilingual_component.
+ */
+#define dvb_multilingual_component_descriptor_components_for_each(d, pos) \
+ for ((pos) = dvb_multilingual_component_descriptor_components_first(d); \
+ (pos); \
+ (pos) = dvb_multilingual_component_descriptor_components_next(d, pos))
+
+/**
+ * Accessor for the text_char field in a dvb_multilingual_component.
+ *
+ * @param e dvb_multilingual_component pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_multilingual_component_text_char(struct dvb_multilingual_component *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_multilingual_component);
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_multilingual_component*
+ dvb_multilingual_component_descriptor_components_first(struct dvb_multilingual_component_descriptor *d)
+{
+ if (d->d.len == 1)
+ return NULL;
+
+ return (struct dvb_multilingual_component *)
+ ((uint8_t*) d + sizeof(struct dvb_multilingual_component_descriptor));
+}
+
+static inline struct dvb_multilingual_component*
+ dvb_multilingual_component_descriptor_components_next(struct dvb_multilingual_component_descriptor *d,
+ struct dvb_multilingual_component *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_multilingual_component) +
+ pos->text_description_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_multilingual_component *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/multilingual_network_name_descriptor.h b/lib/libucsi/dvb/multilingual_network_name_descriptor.h
new file mode 100644
index 0000000..1a7b8c4
--- /dev/null
+++ b/lib/libucsi/dvb/multilingual_network_name_descriptor.h
@@ -0,0 +1,145 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_MULTILINGUAL_NETWORK_NAME_DESCRIPTOR
+#define _UCSI_DVB_MULTILINGUAL_NETWORK_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_multilingual_network_name_descriptor structure.
+ */
+struct dvb_multilingual_network_name_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_multilingual_network_name names[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the names field of a dvb_multilingual_network_name_descriptor.
+ */
+struct dvb_multilingual_network_name {
+ iso639lang_t language_code;
+ uint8_t network_name_length;
+ /* uint8_t name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_multilingual_network_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_multilingual_network_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_multilingual_network_name_descriptor*
+ dvb_multilingual_network_name_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_multilingual_network_name *e =
+ (struct dvb_multilingual_network_name*) (buf + pos);
+
+ pos += sizeof(struct dvb_multilingual_network_name);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e->network_name_length;
+
+ if (pos > len)
+ return NULL;
+ }
+
+ return (struct dvb_multilingual_network_name_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the names field of a dvb_multilingual_network_name_descriptor.
+ *
+ * @param d dvb_multilingual_network_name_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_multilingual_network_name.
+ */
+#define dvb_multilingual_network_name_descriptor_names_for_each(d, pos) \
+ for ((pos) = dvb_multilingual_network_name_descriptor_names_first(d); \
+ (pos); \
+ (pos) = dvb_multilingual_network_name_descriptor_names_next(d, pos))
+
+/**
+ * Accessor for the name field of a dvb_multilingual_network_name.
+ *
+ * @param e dvb_multilingual_network_name pointer.
+ * @return Pointer to the name field.
+ */
+static inline uint8_t *
+ dvb_multilingual_network_name_name(struct dvb_multilingual_network_name *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_multilingual_network_name);
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_multilingual_network_name*
+ dvb_multilingual_network_name_descriptor_names_first(struct dvb_multilingual_network_name_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_multilingual_network_name *)
+ ((uint8_t*) d + sizeof(struct dvb_multilingual_network_name_descriptor));
+}
+
+static inline struct dvb_multilingual_network_name*
+ dvb_multilingual_network_name_descriptor_names_next(struct dvb_multilingual_network_name_descriptor *d,
+ struct dvb_multilingual_network_name *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos +
+ sizeof(struct dvb_multilingual_network_name) +
+ pos->network_name_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_multilingual_network_name *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/multilingual_service_name_descriptor.h b/lib/libucsi/dvb/multilingual_service_name_descriptor.h
new file mode 100644
index 0000000..31bb9c3
--- /dev/null
+++ b/lib/libucsi/dvb/multilingual_service_name_descriptor.h
@@ -0,0 +1,197 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_MULTILINGUAL_SERVICE_NAME_DESCRIPTOR
+#define _UCSI_DVB_MULTILINGUAL_SERVICE_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_multilingual_service_name_descriptor structure.
+ */
+struct dvb_multilingual_service_name_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_multilingual_service_name names[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the service_names field of a dvb_multilingual_service_name_descriptor.
+ */
+struct dvb_multilingual_service_name {
+ iso639lang_t language_code;
+ uint8_t service_provider_name_length;
+ /* uint8_t service_provider_name[] */
+ /* struct dvb_multilingual_service_name_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * Second part of a dvb_multilingual_service_name following the variable length
+ * service_provider_name.
+ */
+struct dvb_multilingual_service_name_part2 {
+ uint8_t service_name_length;
+ /* uint8_t service_name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_multilingual_service_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_multilingual_service_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_multilingual_service_name_descriptor*
+ dvb_multilingual_service_name_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_multilingual_service_name *e =
+ (struct dvb_multilingual_service_name*) (buf+pos);
+ struct dvb_multilingual_service_name_part2 *e2;
+
+ pos += sizeof(struct dvb_multilingual_service_name);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e->service_provider_name_length;
+
+ if (pos > len)
+ return NULL;
+
+ e2 = (struct dvb_multilingual_service_name_part2*) (buf+pos);
+
+ pos += sizeof(struct dvb_multilingual_service_name_part2);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e2->service_name_length;
+
+ if (pos > len)
+ return NULL;
+ }
+
+ return (struct dvb_multilingual_service_name_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the service_name field of a dvb_multilingual_service_name_descriptor.
+ *
+ * @param d dvb_multilingual_service_name_descriptor pointer,
+ * @param pos Variable containing pointer to the current dvb_multilingual_service_name.
+ */
+#define dvb_multilingual_service_name_descriptor_names_for_each(d, pos) \
+ for ((pos) = dvb_multilingual_service_name_descriptor_names_first(d); \
+ (pos); \
+ (pos) = dvb_multilingual_service_name_descriptor_names_next(d, pos))
+
+/**
+ * Accessor for the service_provider_name field of a dvb_multilingual_service_name.
+ *
+ * @param e dvb_multilingual_service_name pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_multilingual_service_name_service_provider_name(struct dvb_multilingual_service_name *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_multilingual_service_name);
+}
+
+/**
+ * Accessor for the dvb_multilingual_service_name_part2 - second part of a
+ * dvb_multilingual_service_name following the service_name field.
+ *
+ * @param e dvb_multilingual_service_name Pointer.
+ * @return dvb_multilingual_service_name_part2 pointer.
+ */
+static inline struct dvb_multilingual_service_name_part2 *
+ dvb_multilingual_service_name_part2(struct dvb_multilingual_service_name *e)
+{
+ return (struct dvb_multilingual_service_name_part2 *)
+ ((uint8_t *) e + sizeof(struct dvb_multilingual_service_name) +
+ e->service_provider_name_length);
+}
+
+/**
+ * Accessor for the service_name field of a dvb_multilingual_service_name_part2.
+ *
+ * @param e dvb_multilingual_service_name_part2 pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_multilingual_service_name_service_name(struct dvb_multilingual_service_name_part2 *e)
+{
+ return (uint8_t *) e + sizeof(struct dvb_multilingual_service_name_part2);
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_multilingual_service_name*
+ dvb_multilingual_service_name_descriptor_names_first(struct dvb_multilingual_service_name_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_multilingual_service_name *)
+ ((uint8_t*) d + sizeof(struct dvb_multilingual_service_name_descriptor));
+}
+
+static inline struct dvb_multilingual_service_name*
+ dvb_multilingual_service_name_descriptor_names_next(struct dvb_multilingual_service_name_descriptor *d,
+ struct dvb_multilingual_service_name *pos)
+{
+ struct dvb_multilingual_service_name_part2 * part2 =
+ dvb_multilingual_service_name_part2(pos);
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) part2+
+ sizeof(struct dvb_multilingual_service_name_part2) +
+ part2->service_name_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_multilingual_service_name *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/network_name_descriptor.h b/lib/libucsi/dvb/network_name_descriptor.h
new file mode 100644
index 0000000..0754597
--- /dev/null
+++ b/lib/libucsi/dvb/network_name_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_NETWORK_NAME_DESCRIPTOR
+#define _UCSI_DVB_NETWORK_NAME_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_network_name_descriptor structure.
+ */
+struct dvb_network_name_descriptor {
+ struct descriptor d;
+
+ /* char name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_network_name_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_network_name_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_network_name_descriptor*
+ dvb_network_name_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_network_name_descriptor*) d;
+}
+
+/**
+ * Accessor for the name field in a dvb_network_name_descriptor.
+ *
+ * @param d dvb_network_name_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_network_name_descriptor_name(struct dvb_network_name_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_network_name_descriptor);
+}
+
+/**
+ * Calculate the length of the name field in a dvb_network_name_descriptor.
+ *
+ * @param d dvb_network_name_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_network_name_descriptor_name_length(struct dvb_network_name_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/nit_section.c b/lib/libucsi/dvb/nit_section.c
new file mode 100644
index 0000000..664a0cb
--- /dev/null
+++ b/lib/libucsi/dvb/nit_section.c
@@ -0,0 +1,78 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/nit_section.h>
+
+struct dvb_nit_section *dvb_nit_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *) ext;
+ struct dvb_nit_section * ret = (struct dvb_nit_section *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct dvb_nit_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+
+ if ((pos + ret->network_descriptors_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, ret->network_descriptors_length))
+ return NULL;
+
+ pos += ret->network_descriptors_length;
+
+ if ((pos + sizeof(struct dvb_nit_section_part2)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+
+ while (pos < len) {
+ struct dvb_nit_transport *transport =
+ (struct dvb_nit_transport *)(buf + pos);
+
+ if ((pos + sizeof(struct dvb_nit_transport)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 2);
+ bswap16(buf + pos + 4);
+
+ pos += sizeof(struct dvb_nit_transport);
+
+ if ((pos + transport->transport_descriptors_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos,
+ transport->transport_descriptors_length))
+ return NULL;
+
+ pos += transport->transport_descriptors_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/nit_section.h b/lib/libucsi/dvb/nit_section.h
new file mode 100644
index 0000000..77ab1a0
--- /dev/null
+++ b/lib/libucsi/dvb/nit_section.h
@@ -0,0 +1,207 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_NIT_SECTION_H
+#define _UCSI_DVB_NIT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_nit_section structure.
+ */
+struct dvb_nit_section {
+ struct section_ext head;
+
+ EBIT2(uint16_t reserved_1 : 4; ,
+ uint16_t network_descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+ /* struct dvb_nit_section_part2 part2 */
+};
+
+/**
+ * Second part of a dvb_nit_section, following the variable length descriptors field.
+ */
+struct dvb_nit_section_part2 {
+ EBIT2(uint16_t reserved_2 : 4; ,
+ uint16_t transport_stream_loop_length :12; );
+ /* struct dvb_nit_transport transports[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the transports field of a dvb_nit_section_part2
+ */
+struct dvb_nit_transport {
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ EBIT2(uint16_t reserved : 4; ,
+ uint16_t transport_descriptors_length :12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_nit_section.
+ *
+ * @param section Generic section_ext pointer.
+ * @return dvb_nit_section pointer, or NULL on error.
+ */
+struct dvb_nit_section * dvb_nit_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the network_id field of a NIT.
+ *
+ * @param nit NIT pointer.
+ * @return The network_id.
+ */
+static inline uint16_t dvb_nit_section_network_id(struct dvb_nit_section *nit)
+{
+ return nit->head.table_id_ext;
+}
+
+/**
+ * Iterator over the descriptors field in a dvb_nit_section.
+ *
+ * @param nit dvb_nit_section pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define dvb_nit_section_descriptors_for_each(nit, pos) \
+ for ((pos) = dvb_nit_section_descriptors_first(nit); \
+ (pos); \
+ (pos) = dvb_nit_section_descriptors_next(nit, pos))
+
+/**
+ * Accessor for a pointer to the dvb_nit_section_part2 structure.
+ *
+ * @param nit dvb_nit_section pointer.
+ * @return dvb_nit_section_part2 pointer.
+ */
+static inline struct dvb_nit_section_part2 *dvb_nit_section_part2(struct dvb_nit_section * nit)
+{
+ return (struct dvb_nit_section_part2 *)
+ ((uint8_t*) nit + sizeof(struct dvb_nit_section) +
+ nit->network_descriptors_length);
+}
+
+/**
+ * Iterator over the transports field in a dvb_nit_section_part2.
+ *
+ * @param nit dvb_nit_section pointer.
+ * @param part2 dvb_nit_section_part2 pointer.
+ * @param pos Pointer to the current dvb_nit_transport.
+ */
+#define dvb_nit_section_transports_for_each(nit, part2, pos) \
+ for ((pos) = dvb_nit_section_transports_first(part2); \
+ (pos); \
+ (pos) = dvb_nit_section_transports_next(part2, pos))
+
+/**
+ * Iterator over the descriptors field in a dvb_nit_transport.
+ *
+ * @param transport dvb_nit_transport pointer.
+ * @param pos Pointer to the current descriptor.
+ */
+#define dvb_nit_transport_descriptors_for_each(transport, pos) \
+ for ((pos) = dvb_nit_transport_descriptors_first(transport); \
+ (pos); \
+ (pos) = dvb_nit_transport_descriptors_next(transport, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ dvb_nit_section_descriptors_first(struct dvb_nit_section * nit)
+{
+ if (nit->network_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) nit + sizeof(struct dvb_nit_section));
+}
+
+static inline struct descriptor *
+ dvb_nit_section_descriptors_next(struct dvb_nit_section * nit,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) nit + sizeof(struct dvb_nit_section),
+ nit->network_descriptors_length,
+ pos);
+}
+
+static inline struct dvb_nit_transport *
+ dvb_nit_section_transports_first(struct dvb_nit_section_part2 *part2)
+{
+ if (part2->transport_stream_loop_length == 0)
+ return NULL;
+
+ return (struct dvb_nit_transport *)
+ ((uint8_t *)part2 + sizeof(struct dvb_nit_section_part2));
+}
+
+static inline struct dvb_nit_transport *
+ dvb_nit_section_transports_next(struct dvb_nit_section_part2 *part2,
+ struct dvb_nit_transport *pos)
+{
+ uint8_t *end = (uint8_t*) part2 + sizeof(struct dvb_nit_section_part2) +
+ part2->transport_stream_loop_length;
+ uint8_t *next = (uint8_t*) pos + sizeof(struct dvb_nit_transport) +
+ pos->transport_descriptors_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_nit_transport *) next;
+}
+
+static inline struct descriptor *
+ dvb_nit_transport_descriptors_first(struct dvb_nit_transport *t)
+{
+ if (t->transport_descriptors_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t*) t + sizeof(struct dvb_nit_transport));
+}
+
+static inline struct descriptor *
+ dvb_nit_transport_descriptors_next(struct dvb_nit_transport *t,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) t + sizeof(struct dvb_nit_transport),
+ t->transport_descriptors_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/nvod_reference_descriptor.h b/lib/libucsi/dvb/nvod_reference_descriptor.h
new file mode 100644
index 0000000..6180514
--- /dev/null
+++ b/lib/libucsi/dvb/nvod_reference_descriptor.h
@@ -0,0 +1,125 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_NVOD_REFERENCE_DESCRIPTOR
+#define _UCSI_DVB_NVOD_REFERENCE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_nvod_reference_descriptor structure.
+ */
+struct dvb_nvod_reference_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_nvod_reference references[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the references field of a dvb_nvod_reference_descriptor.
+ */
+struct dvb_nvod_reference {
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ uint16_t service_id;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_nvod_reference_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure pointer.
+ * @return dvb_nvod_reference_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_nvod_reference_descriptor*
+ dvb_nvod_reference_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_nvod_reference))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ bswap16(buf+pos+4);
+ pos += sizeof(struct dvb_nvod_reference);
+ }
+
+ return (struct dvb_nvod_reference_descriptor*) d;
+}
+
+/**
+ * Iterator over the references field in a dvb_nvod_reference_descriptor.
+ *
+ * @param d dvb_nvod_reference_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_nvod_reference.
+ */
+#define dvb_nvod_reference_descriptor_references_for_each(d, pos) \
+ for ((pos) = dvb_nvod_reference_descriptor_references_first(d); \
+ (pos); \
+ (pos) = dvb_nvod_reference_descriptor_references_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_nvod_reference*
+ dvb_nvod_reference_descriptor_references_first(struct dvb_nvod_reference_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_nvod_reference *)
+ ((uint8_t*) d + sizeof(struct dvb_nvod_reference_descriptor));
+}
+
+static inline struct dvb_nvod_reference*
+ dvb_nvod_reference_descriptor_references_next(struct dvb_nvod_reference_descriptor *d,
+ struct dvb_nvod_reference *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_nvod_reference);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_nvod_reference *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/parental_rating_descriptor.h b/lib/libucsi/dvb/parental_rating_descriptor.h
new file mode 100644
index 0000000..72ecd0a
--- /dev/null
+++ b/lib/libucsi/dvb/parental_rating_descriptor.h
@@ -0,0 +1,135 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_PARENTAL_RATING_DESCRIPTOR
+#define _UCSI_DVB_PARENTAL_RATING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * Defined values for the rating field.
+ */
+enum {
+ DVB_PARENTAL_RATING_MIN_3YEARS = 0x01,
+ DVB_PARENTAL_RATING_MIN_4YEARS = 0x02,
+ DVB_PARENTAL_RATING_MIN_5YEARS = 0x03,
+ DVB_PARENTAL_RATING_MIN_6YEARS = 0x04,
+ DVB_PARENTAL_RATING_MIN_7YEARS = 0x05,
+ DVB_PARENTAL_RATING_MIN_8YEARS = 0x06,
+ DVB_PARENTAL_RATING_MIN_9YEARS = 0x07,
+ DVB_PARENTAL_RATING_MIN_10YEARS = 0x08,
+ DVB_PARENTAL_RATING_MIN_11YEARS = 0x09,
+ DVB_PARENTAL_RATING_MIN_12YEARS = 0x0a,
+ DVB_PARENTAL_RATING_MIN_13YEARS = 0x0b,
+ DVB_PARENTAL_RATING_MIN_14YEARS = 0x0c,
+ DVB_PARENTAL_RATING_MIN_15YEARS = 0x0d,
+ DVB_PARENTAL_RATING_MIN_16YEARS = 0x0e,
+ DVB_PARENTAL_RATING_MIN_17YEARS = 0x0f,
+};
+
+/**
+ * dvb_parental_rating_descriptor structure.
+ */
+struct dvb_parental_rating_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_parental_rating ratings[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ratings field of a dvb_parental_rating_descriptor.
+ */
+struct dvb_parental_rating {
+ iso639country_t country_code;
+ uint8_t rating;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_parental_rating_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_parental_rating_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_parental_rating_descriptor*
+ dvb_parental_rating_descriptor_codec(struct descriptor* d)
+{
+ if (d->len % sizeof(struct dvb_parental_rating))
+ return NULL;
+
+ return (struct dvb_parental_rating_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ratings field of a dvb_parental_rating_descriptor.
+ *
+ * @param d dvb_parental_rating_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_parental_rating.
+ */
+#define dvb_parental_rating_descriptor_ratings_for_each(d, pos) \
+ for ((pos) = dvb_parental_rating_descriptor_ratings_first(d); \
+ (pos); \
+ (pos) = dvb_parental_rating_descriptor_ratings_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_parental_rating*
+ dvb_parental_rating_descriptor_ratings_first(struct dvb_parental_rating_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_parental_rating *)
+ ((uint8_t*) d + sizeof(struct dvb_parental_rating_descriptor));
+}
+
+static inline struct dvb_parental_rating*
+ dvb_parental_rating_descriptor_ratings_next(struct dvb_parental_rating_descriptor *d,
+ struct dvb_parental_rating *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_parental_rating);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_parental_rating *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/partial_transport_stream_descriptor.h b/lib/libucsi/dvb/partial_transport_stream_descriptor.h
new file mode 100644
index 0000000..6e3aa96
--- /dev/null
+++ b/lib/libucsi/dvb/partial_transport_stream_descriptor.h
@@ -0,0 +1,68 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_PARTIAL_TRANSPORT_STREAM_DESCRIPTOR
+#define _UCSI_DVB_PARTIAL_TRANSPORT_STREAM_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_partial_transport_stream_descriptor structure.
+ */
+struct dvb_partial_transport_stream_descriptor {
+ struct descriptor d;
+
+ EBIT6(uint64_t reserved : 2; ,
+ uint64_t peak_rate :22; ,
+ uint64_t reserved_2 : 2; ,
+ uint64_t minimum_overall_smoothing_rate :22; ,
+ uint64_t reserved_3 : 2; ,
+ uint64_t maximum_overall_smoothing_rate :14; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_partial_transport_stream_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_partial_transport_stream_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_partial_transport_stream_descriptor*
+ dvb_partial_transport_stream_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_partial_transport_stream_descriptor) - 2))
+ return NULL;
+
+ bswap64((uint8_t*) d + 2);
+
+ return (struct dvb_partial_transport_stream_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/pdc_descriptor.h b/lib/libucsi/dvb/pdc_descriptor.h
new file mode 100644
index 0000000..68190be
--- /dev/null
+++ b/lib/libucsi/dvb/pdc_descriptor.h
@@ -0,0 +1,64 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_PDC_DESCRIPTOR
+#define _UCSI_DVB_PDC_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_pdc_descriptor structure.
+ */
+struct dvb_pdc_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint32_t reserved : 4; ,
+ uint32_t programme_id_label :20; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_pdc_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return dvb_pdc_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_pdc_descriptor*
+ dvb_pdc_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_pdc_descriptor) - 2))
+ return NULL;
+
+ bswap24((uint8_t*) d + 2);
+
+ return (struct dvb_pdc_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/private_data_specifier_descriptor.h b/lib/libucsi/dvb/private_data_specifier_descriptor.h
new file mode 100644
index 0000000..f4cc03c
--- /dev/null
+++ b/lib/libucsi/dvb/private_data_specifier_descriptor.h
@@ -0,0 +1,63 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_PRIVATE_DATA_SPECIFIER_DESCRIPTOR
+#define _UCSI_DVB_PRIVATE_DATA_SPECIFIER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_private_data_specifier_descriptor structure.
+ */
+struct dvb_private_data_specifier_descriptor {
+ struct descriptor d;
+
+ uint32_t private_data_specifier;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_private_data_specifier_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_private_data_specifier_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_private_data_specifier_descriptor*
+ dvb_private_data_specifier_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_private_data_specifier_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+
+ return (struct dvb_private_data_specifier_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/related_content_descriptor.h b/lib/libucsi/dvb/related_content_descriptor.h
new file mode 100644
index 0000000..fd6a358
--- /dev/null
+++ b/lib/libucsi/dvb/related_content_descriptor.h
@@ -0,0 +1,56 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_RELATED_CONTENT_DESCRIPTOR
+#define _UCSI_DVB_RELATED_CONTENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_related_content_descriptor structure.
+ */
+struct dvb_related_content_descriptor {
+ struct descriptor d;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_related_content_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_related_content_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_related_content_descriptor*
+ dvb_related_content_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_related_content_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/rnt_rar_over_dvb_stream_descriptor.h b/lib/libucsi/dvb/rnt_rar_over_dvb_stream_descriptor.h
new file mode 100644
index 0000000..ba42d12
--- /dev/null
+++ b/lib/libucsi/dvb/rnt_rar_over_dvb_stream_descriptor.h
@@ -0,0 +1,110 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_RNT_RAR_OVER_DVB_STREAM_DESCRIPTOR
+#define _UCSI_DVB_RNT_RAR_OVER_DVB_STREAM_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_rnt_rar_over_dvb_stream_descriptor structure.
+ */
+struct dvb_rnt_rar_over_dvb_stream_descriptor {
+ struct descriptor d;
+
+ dvbdate_t first_valid_date;
+ dvbdate_t last_valid_date;
+ EBIT3(uint8_t weighting : 6; ,
+ uint8_t complete_flag : 1; ,
+ uint8_t scheduled_flag : 1; );
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ uint16_t service_id;
+ uint8_t component_tag;
+ /* struct dvb_rnt_rar_over_dvb_stream_descriptor_scheduled_info scheduled_info */
+} __ucsi_packed;
+
+/**
+ * The scheduled_info field of a dvb_rnt_rar_over_dvb_stream_descriptor (only appears
+ * if scheduled_flag = 1).
+ */
+struct dvb_rnt_rar_over_dvb_stream_descriptor_scheduled_info {
+ dvbdate_t download_start_time;
+ uint8_t download_period_duration;
+ uint8_t download_cycle_time;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_rnt_rar_over_dvb_stream_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_rnt_rar_over_dvb_stream_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_rnt_rar_over_dvb_stream_descriptor*
+ dvb_rnt_rar_over_dvb_stream_descriptor_codec(struct descriptor* d)
+{
+ uint8_t *buf = (uint8_t*) d;
+ uint32_t len = d->len + 2;
+ struct dvb_rnt_rar_over_dvb_stream_descriptor *ret =
+ (struct dvb_rnt_rar_over_dvb_stream_descriptor *) buf;
+
+ if (len < sizeof(struct dvb_rnt_rar_over_dvb_stream_descriptor))
+ return NULL;
+
+ bswap16(buf + 13);
+ bswap16(buf + 15);
+ bswap16(buf + 17);
+
+ if (ret->scheduled_flag == 1) {
+ if (len < (sizeof(struct dvb_rnt_rar_over_dvb_stream_descriptor)+
+ sizeof(struct dvb_rnt_rar_over_dvb_stream_descriptor_scheduled_info)))
+ return NULL;
+ }
+
+ return ret;
+}
+
+/**
+ * Accessor for the scheduled_info field of a dvb_rnt_rar_over_dvb_stream_descriptor.
+ *
+ * @param d dvb_rnt_rar_over_dvb_stream_descriptor pointer.
+ * @return Pointer, or NULL on error.
+ */
+static inline struct dvb_rnt_rar_over_dvb_stream_descriptor_scheduled_info*
+ dvb_rnt_rar_over_dvb_stream_descriptor_scheduled_info(struct dvb_rnt_rar_over_dvb_stream_descriptor *d)
+{
+ if (d->scheduled_flag != 1)
+ return NULL;
+ return (struct dvb_rnt_rar_over_dvb_stream_descriptor_scheduled_info*)
+ ((uint8_t*) d + sizeof(struct dvb_rnt_rar_over_dvb_stream_descriptor));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/rnt_rar_over_ip_descriptor.h b/lib/libucsi/dvb/rnt_rar_over_ip_descriptor.h
new file mode 100644
index 0000000..b1f2da4
--- /dev/null
+++ b/lib/libucsi/dvb/rnt_rar_over_ip_descriptor.h
@@ -0,0 +1,87 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_RNT_RAR_OVER_IP_DESCRIPTOR
+#define _UCSI_DVB_RNT_RAR_OVER_IP_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_rnt_rar_over_ip_descriptor structure.
+ */
+struct dvb_rnt_rar_over_ip_descriptor {
+ struct descriptor d;
+
+ dvbdate_t first_valid_date;
+ dvbdate_t last_valid_date;
+ EBIT3(uint8_t weighting : 6; ,
+ uint8_t complete_flag : 1; ,
+ uint8_t reserved : 1; );
+ uint8_t url_length;
+ /* uint8_t url[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_rnt_rar_over_ip_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_rnt_rar_over_ip_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_rnt_rar_over_ip_descriptor*
+ dvb_rnt_rar_over_ip_descriptor_codec(struct descriptor* d)
+{
+ uint8_t *buf = (uint8_t*) d;
+ uint32_t len = d->len + 2;
+ struct dvb_rnt_rar_over_ip_descriptor *ret =
+ (struct dvb_rnt_rar_over_ip_descriptor *) buf;
+
+ if (len < sizeof(struct dvb_rnt_rar_over_ip_descriptor))
+ return NULL;
+ if (len < (sizeof(struct dvb_rnt_rar_over_ip_descriptor) + buf[13]))
+ return NULL;
+
+ return ret;
+}
+
+/**
+ * Accessor for the url field of a dvb_rnt_rar_over_ip_descriptor.
+ *
+ * @param d dvb_rnt_rar_over_ip_descriptor pointer.
+ * @return Pointer.
+ */
+static inline uint8_t*
+ dvb_rnt_rar_over_ip_descriptor_url(struct dvb_rnt_rar_over_ip_descriptor *d)
+{
+ return (uint8_t*)
+ ((uint8_t*) d + sizeof(struct dvb_rnt_rar_over_ip_descriptor));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/rnt_rnt_scan_descriptor.h b/lib/libucsi/dvb/rnt_rnt_scan_descriptor.h
new file mode 100644
index 0000000..cb74f75
--- /dev/null
+++ b/lib/libucsi/dvb/rnt_rnt_scan_descriptor.h
@@ -0,0 +1,125 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_RNT_RNT_SCAN_DESCRIPTOR
+#define _UCSI_DVB_RNT_RNT_SCAN_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_rnt_rnt_scan_descriptor structure.
+ */
+struct dvb_rnt_rnt_scan_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_rnt_rnt_scan_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a dvb_rnt_rnt_scan_descriptor.
+ */
+struct dvb_rnt_rnt_scan_entry {
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ uint8_t scan_weighting;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_rnt_rnt_scan_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_rnt_rnt_scan_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_rnt_rnt_scan_descriptor*
+ dvb_rnt_rnt_scan_descriptor_codec(struct descriptor* d)
+{
+ uint8_t *buf = (uint8_t*) d;
+ uint32_t len = d->len +2;
+ uint32_t pos = 2;
+
+ if ((len-2) % sizeof(struct dvb_rnt_rnt_scan_entry))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ pos += sizeof(struct dvb_rnt_rnt_scan_entry);
+ }
+
+ return (struct dvb_rnt_rnt_scan_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field of a dvb_rnt_rnt_scan_descriptor.
+ *
+ * @param d dvb_rnt_rnt_scan_descriptor pointer.
+ * @param pos Variable holding a pointer to the current dvb_rnt_rnt_scan_entry.
+ */
+#define dvb_rnt_rnt_scan_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_rnt_rnt_scan_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_rnt_rnt_scan_descriptor_entries_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_rnt_rnt_scan_entry*
+ dvb_rnt_rnt_scan_descriptor_entries_first(struct dvb_rnt_rnt_scan_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_rnt_rnt_scan_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_rnt_rnt_scan_descriptor));
+}
+
+static inline struct dvb_rnt_rnt_scan_entry*
+ dvb_rnt_rnt_scan_descriptor_entries_next(struct dvb_rnt_rnt_scan_descriptor *d,
+ struct dvb_rnt_rnt_scan_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_rnt_rnt_scan_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_rnt_rnt_scan_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/rst_section.c b/lib/libucsi/dvb/rst_section.c
new file mode 100644
index 0000000..259d2b0
--- /dev/null
+++ b/lib/libucsi/dvb/rst_section.c
@@ -0,0 +1,47 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/rst_section.h>
+
+struct dvb_rst_section * dvb_rst_section_codec(struct section *section)
+{
+ uint8_t * buf = (uint8_t *) section;
+ size_t pos = sizeof(struct section);
+ size_t len = section_length(section);
+ struct dvb_rst_section * ret = (struct dvb_rst_section *) section;
+
+ while (pos < len) {
+ if ((pos + sizeof(struct dvb_rst_status)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 2);
+ bswap16(buf + pos + 4);
+ bswap16(buf + pos + 6);
+
+ pos += sizeof(struct dvb_rst_status);
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/rst_section.h b/lib/libucsi/dvb/rst_section.h
new file mode 100644
index 0000000..4b3360b
--- /dev/null
+++ b/lib/libucsi/dvb/rst_section.h
@@ -0,0 +1,110 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_RST_SECTION_H
+#define _UCSI_DVB_RST_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_rst_section structure.
+ */
+struct dvb_rst_section {
+ struct section head;
+
+ /* struct dvb_rst_status statuses[] */
+};
+
+/**
+ * An entry in the statuses field of a dvb_rst_section structure.
+ */
+struct dvb_rst_status {
+ uint16_t transport_stream_id;
+ uint16_t original_network_id;
+ uint16_t service_id;
+ uint16_t event_id;
+ EBIT2(uint8_t reserved : 5; ,
+ uint8_t running_status : 3; );
+};
+
+/**
+ * Process a dvb_rst_section.
+ *
+ * @param section Pointer to a generic section strcuture.
+ * @return dvb_rst_section pointer, or NULL on error.
+ */
+struct dvb_rst_section *dvb_rst_section_codec(struct section *section);
+
+/**
+ * Iterator for entries in the statuses field of a dvb_rst_section.
+ *
+ * @param rst dvb_rst_section pointer.
+ * @param pos Variable containing a pointer to the current dvb_rst_status.
+ */
+#define dvb_rst_section_statuses_for_each(rst, pos) \
+ for ((pos) = dvb_rst_section_statuses_first(rst); \
+ (pos); \
+ (pos) = dvb_rst_section_statuses_next(rst, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_rst_status *
+ dvb_rst_section_statuses_first(struct dvb_rst_section *rst)
+{
+ size_t pos = sizeof(struct dvb_rst_section);
+
+ if (pos >= section_length(&rst->head))
+ return NULL;
+
+ return (struct dvb_rst_status*) ((uint8_t *) rst + pos);
+}
+
+static inline struct dvb_rst_status *
+ dvb_rst_section_statuses_next(struct dvb_rst_section * rst,
+ struct dvb_rst_status * pos)
+{
+ uint8_t *end = (uint8_t*) rst + section_length(&rst->head);
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_rst_status);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_rst_status *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/s2_satellite_delivery_descriptor.h b/lib/libucsi/dvb/s2_satellite_delivery_descriptor.h
new file mode 100644
index 0000000..8f9fea8
--- /dev/null
+++ b/lib/libucsi/dvb/s2_satellite_delivery_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_S2_SATELLITE_DELIVERY_DESCRIPTOR
+#define _UCSI_DVB_S2_SATELLITE_DELIVERY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_s2_satellite_delivery_descriptor structure.
+ */
+struct dvb_s2_satellite_delivery_descriptor {
+ struct descriptor d;
+
+ EBIT4(uint8_t scrambling_sequence_selector : 1; ,
+ uint8_t multiple_input_stream : 1; ,
+ uint8_t backwards_compatability : 1; ,
+ uint8_t reserved : 5; );
+ /* uint32_t scrambling_sequence_index if scrambling_sequence_selector = 1 */
+ /* uint8_t input_stream_id if multiple_input_stream = 1 */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_s2_satellite_delivery_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return dvb_s2_satellite_delivery_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_s2_satellite_delivery_descriptor*
+ dvb_s2_satellite_delivery_descriptor_codec(struct descriptor* d)
+{
+ struct dvb_s2_satellite_delivery_descriptor *s2 =
+ (struct dvb_s2_satellite_delivery_descriptor*) d;
+
+ if (d->len < (sizeof(struct dvb_s2_satellite_delivery_descriptor) - 2))
+ return NULL;
+
+ int len = sizeof(struct dvb_s2_satellite_delivery_descriptor);
+ if (s2->scrambling_sequence_selector) {
+ len += 3;
+ }
+ if (s2->multiple_input_stream) {
+ len += 1;
+ }
+
+ if (d->len < len)
+ return NULL;
+
+ return s2;
+}
+
+/**
+ * Accessor for the scrambling_sequence_index field of a dvb_s2_satellite_delivery_descriptor.
+ *
+ * @param s2 dvb_s2_satellite_delivery_descriptor pointer.
+ * @return The scrambling_sequence_index.
+ */
+static inline uint32_t dvb_s2_satellite_delivery_descriptor_scrambling_sequence_index(struct dvb_s2_satellite_delivery_descriptor *s2)
+{
+ uint8_t *tmp = (uint8_t*) s2;
+
+ if (s2->scrambling_sequence_selector) {
+ return ((tmp[4] & 0x03) << 16) | (tmp[5] << 8) | tmp[6];
+ }
+ return 0;
+}
+
+/**
+ * Accessor for the input_stream_id field of a dvb_s2_satellite_delivery_descriptor.
+ *
+ * @param s2 dvb_s2_satellite_delivery_descriptor pointer.
+ * @return The input_stream_id.
+ */
+static inline uint8_t dvb_s2_satellite_delivery_descriptor_input_stream_id(struct dvb_s2_satellite_delivery_descriptor *s2)
+{
+ uint8_t *tmp = (uint8_t*) s2;
+
+ if (!s2->multiple_input_stream)
+ return 0;
+
+ int off = 3;
+ if (s2->scrambling_sequence_selector) {
+ off += 3;
+ }
+ return tmp[off];
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/satellite_delivery_descriptor.h b/lib/libucsi/dvb/satellite_delivery_descriptor.h
new file mode 100644
index 0000000..b93d052
--- /dev/null
+++ b/lib/libucsi/dvb/satellite_delivery_descriptor.h
@@ -0,0 +1,73 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SATELLITE_DELIVERY_DESCRIPTOR
+#define _UCSI_DVB_SATELLITE_DELIVERY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_satellite_delivery_descriptor structure.
+ */
+struct dvb_satellite_delivery_descriptor {
+ struct descriptor d;
+
+ uint32_t frequency; // BCD, units 10kHz
+ uint16_t orbital_position;
+ EBIT5(uint8_t west_east_flag : 1; ,
+ uint8_t polarization : 2; ,
+ uint8_t roll_off : 2; ,
+ uint8_t modulation_system : 1; ,
+ uint8_t modulation_type : 2; );
+ EBIT2(uint32_t symbol_rate : 28; , // BCD, units 100Hz
+ uint32_t fec_inner : 4; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_satellite_delivery_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return dvb_satellite_delivery_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_satellite_delivery_descriptor*
+ dvb_satellite_delivery_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_satellite_delivery_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+ bswap16((uint8_t*) d + 6);
+ bswap32((uint8_t*) d + 9);
+
+ return (struct dvb_satellite_delivery_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/scrambling_descriptor.h b/lib/libucsi/dvb/scrambling_descriptor.h
new file mode 100644
index 0000000..4669bc8
--- /dev/null
+++ b/lib/libucsi/dvb/scrambling_descriptor.h
@@ -0,0 +1,61 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SCRAMBLING_DESCRIPTOR
+#define _UCSI_DVB_SCRAMBLING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_scrambling_descriptor structure.
+ */
+struct dvb_scrambling_descriptor {
+ struct descriptor d;
+
+ uint8_t scrambling_mode;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_scrambling_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to dvb_scrambling_descriptor, or NULL on error.
+ */
+static inline struct dvb_scrambling_descriptor*
+ dvb_scrambling_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_scrambling_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_scrambling_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/sdt_section.c b/lib/libucsi/dvb/sdt_section.c
new file mode 100644
index 0000000..4c7824c
--- /dev/null
+++ b/lib/libucsi/dvb/sdt_section.c
@@ -0,0 +1,60 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/sdt_section.h>
+
+struct dvb_sdt_section * dvb_sdt_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct dvb_sdt_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 3;
+
+ while (pos < len) {
+ struct dvb_sdt_service * service =
+ (struct dvb_sdt_service *)(buf + pos);
+
+ if ((pos + sizeof(struct dvb_sdt_service)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 3);
+ pos += sizeof(struct dvb_sdt_service);
+
+ if ((pos + service->descriptors_loop_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, service->descriptors_loop_length))
+ return NULL;
+
+ pos += service->descriptors_loop_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct dvb_sdt_section *) ext;
+}
diff --git a/lib/libucsi/dvb/sdt_section.h b/lib/libucsi/dvb/sdt_section.h
new file mode 100644
index 0000000..03a8569
--- /dev/null
+++ b/lib/libucsi/dvb/sdt_section.h
@@ -0,0 +1,157 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SDT_SECTION_H
+#define _UCSI_DVB_SDT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_sdt_section structure.
+ */
+struct dvb_sdt_section {
+ struct section_ext head;
+
+ uint16_t original_network_id;
+ uint8_t reserved;
+ /* struct dvb_sdt_service services[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the services field of a dvb_sdt_section.
+ */
+struct dvb_sdt_service {
+ uint16_t service_id;
+ EBIT3(uint8_t reserved : 6; ,
+ uint8_t eit_schedule_flag : 1; ,
+ uint8_t eit_present_following_flag : 1; );
+ EBIT3(uint16_t running_status : 3; ,
+ uint16_t free_ca_mode : 1; ,
+ uint16_t descriptors_loop_length :12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_sdt_section.
+ *
+ * @param section Pointer to a generic section_ext structure.
+ * @return dvb_sdt_section pointer, or NULL on error.
+ */
+struct dvb_sdt_section * dvb_sdt_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the transport_stream_id field of an SDT.
+ *
+ * @param sdt SDT pointer.
+ * @return The transport_stream_id.
+ */
+static inline uint16_t dvb_sdt_section_transport_stream_id(struct dvb_sdt_section *sdt)
+{
+ return sdt->head.table_id_ext;
+}
+
+/**
+ * Iterator for the services field in a dvb_sdt_section.
+ *
+ * @param sdt dvb_sdt_section pointer.
+ * @param pos Variable containing a pointer to the current dvb_sdt_service.
+ */
+#define dvb_sdt_section_services_for_each(sdt, pos) \
+ for ((pos) = dvb_sdt_section_services_first(sdt); \
+ (pos); \
+ (pos) = dvb_sdt_section_services_next(sdt, pos))
+
+/**
+ * Iterator for the descriptors field in a dvb_sdt_service.
+ *
+ * @param service dvb_sdt_service pointer.
+ * @param pos Variable containing a pointer to the current descriptor.
+ */
+#define dvb_sdt_service_descriptors_for_each(service, pos) \
+ for ((pos) = dvb_sdt_service_descriptors_first(service); \
+ (pos); \
+ (pos) = dvb_sdt_service_descriptors_next(service, pos))
+
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_sdt_service *
+ dvb_sdt_section_services_first(struct dvb_sdt_section * sdt)
+{
+ size_t pos = sizeof(struct dvb_sdt_section);
+
+ if (pos >= section_ext_length(&sdt->head))
+ return NULL;
+
+ return (struct dvb_sdt_service*) ((uint8_t *) sdt + pos);
+}
+
+static inline struct dvb_sdt_service *
+ dvb_sdt_section_services_next(struct dvb_sdt_section * sdt,
+ struct dvb_sdt_service * pos)
+{
+ uint8_t *end = (uint8_t*) sdt + section_ext_length(&sdt->head);
+ uint8_t *next = (uint8_t*) pos + sizeof(struct dvb_sdt_service) +
+ pos->descriptors_loop_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_sdt_service *) next;
+}
+
+static inline struct descriptor *
+ dvb_sdt_service_descriptors_first(struct dvb_sdt_service *svc)
+{
+ if (svc->descriptors_loop_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t*) svc + sizeof(struct dvb_sdt_service));
+}
+
+static inline struct descriptor *
+ dvb_sdt_service_descriptors_next(struct dvb_sdt_service *svc,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) svc + sizeof(struct dvb_sdt_service),
+ svc->descriptors_loop_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/section.h b/lib/libucsi/dvb/section.h
new file mode 100644
index 0000000..8488d71
--- /dev/null
+++ b/lib/libucsi/dvb/section.h
@@ -0,0 +1,107 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SECTION_H
+#define _UCSI_DVB_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/dvb/bat_section.h>
+#include <libucsi/dvb/dit_section.h>
+#include <libucsi/dvb/eit_section.h>
+#include <libucsi/dvb/nit_section.h>
+#include <libucsi/dvb/rst_section.h>
+#include <libucsi/dvb/sdt_section.h>
+#include <libucsi/dvb/sit_section.h>
+#include <libucsi/dvb/st_section.h>
+#include <libucsi/dvb/tdt_section.h>
+#include <libucsi/dvb/tot_section.h>
+#include <libucsi/dvb/tva_container_section.h>
+#include <libucsi/dvb/int_section.h>
+
+/**
+ * The following are not implemented just now.
+ */
+/*
+#include <libucsi/dvb/tva_related_content_section.h>
+#include <libucsi/dvb/tva_content_identifier_section.h>
+#include <libucsi/dvb/tva_resolution_provider_notification_section.h>
+#include <libucsi/dvb/ait_section.h>
+#include <libucsi/dvb/cit_section.h>
+#include <libucsi/dvb/rct_section.h>
+#include <libucsi/dvb/rnt_section.h>
+*/
+
+#define TRANSPORT_NIT_PID 0x10
+#define TRANSPORT_SDT_PID 0x11
+#define TRANSPORT_BAT_PID 0x11
+#define TRANSPORT_EIT_PID 0x12
+#define TRANSPORT_CIT_PID 0x12
+#define TRANSPORT_RST_PID 0x13
+#define TRANSPORT_TDT_PID 0x14
+#define TRANSPORT_TOT_PID 0x14
+#define TRANSPORT_RNT_PID 0x16
+#define TRANSPORT_DIT_PID 0x1e
+#define TRANSPORT_SIT_PID 0x1f
+
+/**
+ * Enumeration of DVB section tags.
+ */
+enum dvb_section_tag {
+ stag_dvb_network_information_actual = 0x40,
+ stag_dvb_network_information_other = 0x41,
+
+ stag_dvb_service_description_actual = 0x42,
+ stag_dvb_service_description_other = 0x46,
+
+ stag_dvb_bouquet_association = 0x4a,
+ stag_dvb_update_notification = 0x4b, /* same syntax as IP_MAC */
+ stag_dvb_ip_mac_notification = 0x4c,
+
+ stag_dvb_event_information_nownext_actual = 0x4e,
+ stag_dvb_event_information_nownext_other = 0x4f,
+ stag_dvb_event_information_schedule_actual = 0x50, /* 0x50->0x5f */
+ stag_dvb_event_information_schedule_other = 0x60, /* 0x60->0x6f */
+
+ stag_dvb_time_date = 0x70,
+ stag_dvb_running_status = 0x71,
+ stag_dvb_stuffing = 0x72,
+ stag_dvb_time_offset = 0x73,
+ stag_dvb_application_information = 0x74,
+ stag_dvb_tva_container = 0x75,
+ stag_dvb_tva_related_content = 0x76,
+ stag_dvb_tva_content_identifier = 0x77,
+ stag_dvb_mpe_fec = 0x78,
+ stag_dvb_tva_resolution_provider_notification = 0x79,
+
+ stag_dvb_discontinuity_information = 0x7e,
+ stag_dvb_selection_information = 0x7f,
+
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/service_availability_descriptor.h b/lib/libucsi/dvb/service_availability_descriptor.h
new file mode 100644
index 0000000..64def75
--- /dev/null
+++ b/lib/libucsi/dvb/service_availability_descriptor.h
@@ -0,0 +1,98 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SERVICE_AVAILABILITY_DESCRIPTOR
+#define _UCSI_DVB_SERVICE_AVAILABILITY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_service_availability_descriptor structure.
+ */
+struct dvb_service_availability_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t availability_flag : 1; ,
+ uint8_t reserved : 7; );
+ /* uint16_t cell_ids[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_service_availability_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return dvb_service_availability_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_service_availability_descriptor*
+ dvb_service_availability_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint8_t* buf = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ pos += sizeof(struct dvb_service_availability_descriptor) - 2;
+
+ if ((len - pos) % 2)
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ pos += 2;
+ }
+
+ return (struct dvb_service_availability_descriptor*) d;
+}
+
+/**
+ * Accessor for the cell_ids field of a dvb_service_availability_descriptor.
+ *
+ * @param d dvb_service_availability_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint16_t *
+ dvb_service_availability_descriptor_cell_ids(struct dvb_service_availability_descriptor *d)
+{
+ return (uint16_t *) ((uint8_t *) d + sizeof(struct dvb_service_availability_descriptor));
+}
+
+/**
+ * Determine the number of entries in the cell_ids field of a dvb_service_availability_descriptor.
+ *
+ * @param d dvb_service_availability_descriptor pointer.
+ * @return The number of entries.
+ */
+static inline int
+ dvb_service_availability_descriptor_cell_ids_count(struct dvb_service_availability_descriptor *d)
+{
+ return (d->d.len - 1) >> 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/service_descriptor.h b/lib/libucsi/dvb/service_descriptor.h
new file mode 100644
index 0000000..dd0f0ec
--- /dev/null
+++ b/lib/libucsi/dvb/service_descriptor.h
@@ -0,0 +1,163 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SERVICE_DESCRIPTOR
+#define _UCSI_DVB_SERVICE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for service_type.
+ */
+enum {
+ DVB_SERVICE_TYPE_DIGITAL_TV = 0x01,
+ DVB_SERVICE_TYPE_DIGITAL_RADIO = 0x02,
+ DVB_SERVICE_TYPE_TELETEXT = 0x03,
+ DVB_SERVICE_TYPE_NVOD_REF = 0x04,
+ DVB_SERVICE_TYPE_NVOD_TIMESHIFT = 0x05,
+ DVB_SERVICE_TYPE_MOSAIC = 0x06,
+ DVB_SERVICE_TYPE_PAL = 0x07,
+ DVB_SERVICE_TYPE_SECAM = 0x08,
+ DVB_SERVICE_TYPE_D_D2_MAC = 0x09,
+ DVB_SERVICE_TYPE_FM_RADIO = 0x0a,
+ DVB_SERVICE_TYPE_NTSC = 0x0b,
+ DVB_SERVICE_TYPE_DATA_BCAST = 0x0c,
+ DVB_SERVICE_TYPE_EN50221 = 0x0d,
+ DVB_SERVICE_TYPE_RCS_MAP = 0x0e,
+ DVB_SERVICE_TYPE_RCS_FLS = 0x0f,
+ DVB_SERVICE_TYPE_MHP = 0x10,
+ DVB_SERVICE_TYPE_MPEG2_HD_DIGITAL_TV = 0x11,
+ DVB_SERVICE_TYPE_ADVANCED_CODEC_SD_DIGITAL_TV = 0x16,
+ DVB_SERVICE_TYPE_ADVANCED_CODEC_SD_NVOD_TIMESHIFT = 0x17,
+ DVB_SERVICE_TYPE_ADVANCED_CODEC_SD_NVOD_REF = 0x18,
+ DVB_SERVICE_TYPE_ADVANCED_CODEC_HD_DIGITAL_TV = 0x19,
+ DVB_SERVICE_TYPE_ADVANCED_CODEC_HD_NVOD_TIMESHIFT = 0x1a,
+ DVB_SERVICE_TYPE_ADVANCED_CODEC_HD_NVOD_REF = 0x1b,
+};
+
+/**
+ * dvb_service_descriptor structure.
+ */
+struct dvb_service_descriptor {
+ struct descriptor d;
+
+ uint8_t service_type;
+ uint8_t service_provider_name_length;
+ /* uint8_t service_provider_name[] */
+ /* struct dvb_service_descriptor_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * Second part of a dvb_service_descriptor following the variable length
+ * service_provider_name field.
+ */
+struct dvb_service_descriptor_part2 {
+ uint8_t service_name_length;
+ /* uint8_t service_name[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_service_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_service_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_service_descriptor*
+ dvb_service_descriptor_codec(struct descriptor* d)
+{
+ struct dvb_service_descriptor *p =
+ (struct dvb_service_descriptor *) d;
+ struct dvb_service_descriptor_part2 *p2;
+ uint32_t pos = sizeof(struct dvb_service_descriptor) - 2;
+ uint32_t len = d->len;
+
+ if (pos > len)
+ return NULL;
+
+ pos += p->service_provider_name_length;
+
+ if (pos > len)
+ return NULL;
+
+ p2 = (struct dvb_service_descriptor_part2*) ((uint8_t*) d + 2 + pos);
+
+ pos += sizeof(struct dvb_service_descriptor_part2);
+
+ if (pos > len)
+ return NULL;
+
+ pos += p2->service_name_length;
+
+ if (pos != len)
+ return NULL;
+
+ return p;
+}
+
+/**
+ * Accessor for the service_provider_name field of a dvb_service_descriptor.
+ *
+ * @param d dvb_service_descriptor pointer.
+ * @return Pointer to the service_provider_name field.
+ */
+static inline uint8_t *
+ dvb_service_descriptor_service_provider_name(struct dvb_service_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_service_descriptor);
+}
+
+/**
+ * Accessor for the second part of a dvb_service_descriptor.
+ *
+ * @param d dvb_service_descriptor pointer.
+ * @return dvb_service_descriptor_part2 pointer.
+ */
+static inline struct dvb_service_descriptor_part2 *
+ dvb_service_descriptor_part2(struct dvb_service_descriptor *d)
+{
+ return (struct dvb_service_descriptor_part2 *)
+ ((uint8_t*) d + sizeof(struct dvb_service_descriptor) +
+ d->service_provider_name_length);
+}
+
+/**
+ * Accessor for the service_name field of a dvb_service_descriptor_part2.
+ *
+ * @param d dvb_service_descriptor_part2 pointer.
+ * @return Pointer to the service_name field.
+ */
+static inline uint8_t *
+ dvb_service_descriptor_service_name(struct dvb_service_descriptor_part2 *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_service_descriptor_part2);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/service_identifier_descriptor.h b/lib/libucsi/dvb/service_identifier_descriptor.h
new file mode 100644
index 0000000..2037a05
--- /dev/null
+++ b/lib/libucsi/dvb/service_identifier_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SERVICE_IDENTIFIER_DESCRIPTOR
+#define _UCSI_DVB_SERVICE_IDENTIFIER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_service_identifier_descriptor.
+ */
+struct dvb_service_identifier_descriptor {
+ struct descriptor d;
+
+ /* uint8_t identifier[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_service_identifier_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_service_identifier_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_service_identifier_descriptor*
+ dvb_service_identifier_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_service_identifier_descriptor*) d;
+}
+
+/**
+ * Retrieve a pointer to the identifier field of a dvb_service_identifier_descriptor.
+ *
+ * @param d dvb_service_identifier_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_service_identifier_descriptor_identifier(struct dvb_service_identifier_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_service_identifier_descriptor);
+}
+
+/**
+ * Calculate length of the identifier field of a dvb_service_identifier_descriptor.
+ *
+ * @param d dvb_service_identifier_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ dvb_service_identifier_descriptor_identifier_length(struct dvb_service_identifier_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/service_list_descriptor.h b/lib/libucsi/dvb/service_list_descriptor.h
new file mode 100644
index 0000000..0086b25
--- /dev/null
+++ b/lib/libucsi/dvb/service_list_descriptor.h
@@ -0,0 +1,122 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SERVICE_LIST_DESCRIPTOR
+#define _UCSI_DVB_SERVICE_LIST_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_service_list_descriptor structure.
+ */
+struct dvb_service_list_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_service_list_service services[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the services field of a dvb_service_list_descriptor.
+ */
+struct dvb_service_list_service {
+ uint16_t service_id;
+ uint8_t service_type;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_service_list_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_service_list_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_service_list_descriptor*
+ dvb_service_list_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+ uint8_t *p = (uint8_t*) d + 2;
+
+ if (len % sizeof(struct dvb_service_list_service))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(p+pos);
+ pos += sizeof(struct dvb_service_list_service);
+ }
+
+ return (struct dvb_service_list_descriptor*) d;
+}
+
+/**
+ * Iterator for services field in a dvb_service_list_descriptor.
+ *
+ * @param d dvb_service_list_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_service_list_service.
+ */
+#define dvb_service_list_descriptor_services_for_each(d, pos) \
+ for ((pos) = dvb_service_list_descriptor_services_first(d); \
+ (pos); \
+ (pos) = dvb_service_list_descriptor_services_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_service_list_service*
+ dvb_service_list_descriptor_services_first(struct dvb_service_list_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_service_list_service *)
+ ((uint8_t*) d + sizeof(struct dvb_service_list_descriptor));
+}
+
+static inline struct dvb_service_list_service*
+ dvb_service_list_descriptor_services_next(struct dvb_service_list_descriptor *d,
+ struct dvb_service_list_service *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_service_list_service);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_service_list_service *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/service_move_descriptor.h b/lib/libucsi/dvb/service_move_descriptor.h
new file mode 100644
index 0000000..7685e65
--- /dev/null
+++ b/lib/libucsi/dvb/service_move_descriptor.h
@@ -0,0 +1,67 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SERVICE_MOVE_DESCRIPTOR
+#define _UCSI_DVB_SERVICE_MOVE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_service_move_descriptor structure.
+ */
+struct dvb_service_move_descriptor {
+ struct descriptor d;
+
+ uint16_t new_original_network_id;
+ uint16_t new_transport_stream_id;
+ uint16_t new_service_id;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_service_move_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to dvb_service_move_descriptor, or NULL on error.
+ */
+static inline struct dvb_service_move_descriptor*
+ dvb_service_move_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_service_move_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+ bswap16((uint8_t*) d + 4);
+ bswap16((uint8_t*) d + 6);
+
+ return (struct dvb_service_move_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/short_event_descriptor.h b/lib/libucsi/dvb/short_event_descriptor.h
new file mode 100644
index 0000000..449c6f0
--- /dev/null
+++ b/lib/libucsi/dvb/short_event_descriptor.h
@@ -0,0 +1,135 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SHORT_EVENT_DESCRIPTOR
+#define _UCSI_DVB_SHORT_EVENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_short_event_descriptor structure.
+ */
+struct dvb_short_event_descriptor {
+ struct descriptor d;
+
+ iso639lang_t language_code;
+ uint8_t event_name_length;
+ /* uint8_t event_name[] */
+ /* struct dvb_short_event_descriptor_part2 part2 */
+} __ucsi_packed;
+
+/**
+ * Second part of a dvb_short_event_descriptor, following the variable length
+ * name field.
+ */
+struct dvb_short_event_descriptor_part2 {
+ uint8_t text_length;
+ /* uint8_t text[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_short_event_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_short_event_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_short_event_descriptor*
+ dvb_short_event_descriptor_codec(struct descriptor* d)
+{
+ struct dvb_short_event_descriptor *p =
+ (struct dvb_short_event_descriptor*) d;
+ struct dvb_short_event_descriptor_part2 *p2;
+ uint32_t pos = sizeof(struct dvb_short_event_descriptor) - 2;
+ uint32_t len = d->len;
+
+ if (pos > len)
+ return NULL;
+
+ pos += p->event_name_length;
+
+ if (pos > len)
+ return NULL;
+
+ p2 = (struct dvb_short_event_descriptor_part2*) ((uint8_t*) d + 2 + pos);
+
+ pos += sizeof(struct dvb_short_event_descriptor_part2);
+
+ if (pos > len)
+ return NULL;
+
+ pos += p2->text_length;
+
+ if (pos != len)
+ return NULL;
+
+ return p;
+}
+
+/**
+ * Accessor for name field in a dvb_short_event_descriptor.
+ *
+ * @param d dvb_short_event_descriptor pointer.
+ * @return Pointer to name field.
+ */
+static inline uint8_t *
+ dvb_short_event_descriptor_event_name(struct dvb_short_event_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_short_event_descriptor);
+}
+
+/**
+ * Accessor for second part of a dvb_short_event_descriptor.
+ *
+ * @param d dvb_short_event_descriptor pointer.
+ * @return dvb_short_event_descriptor_part2 pointer.
+ */
+static inline struct dvb_short_event_descriptor_part2 *
+ dvb_short_event_descriptor_part2(struct dvb_short_event_descriptor *d)
+{
+ return (struct dvb_short_event_descriptor_part2 *)
+ ((uint8_t*) d + sizeof(struct dvb_short_event_descriptor) +
+ d->event_name_length);
+}
+
+/**
+ * Accessor for text field in a dvb_short_event_descriptor_part2.
+ *
+ * @param d dvb_short_event_descriptor_part2 pointer.
+ * @return Pointer to text field.
+ */
+static inline uint8_t *
+ dvb_short_event_descriptor_text(struct dvb_short_event_descriptor_part2 *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_short_event_descriptor_part2);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/short_smoothing_buffer_descriptor.h b/lib/libucsi/dvb/short_smoothing_buffer_descriptor.h
new file mode 100644
index 0000000..e52d20a
--- /dev/null
+++ b/lib/libucsi/dvb/short_smoothing_buffer_descriptor.h
@@ -0,0 +1,87 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SHORT_SMOOTHING_BUFFER_DESCRIPTOR
+#define _UCSI_DVB_SHORT_SMOOTHING_BUFFER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_short_smoothing_buffer_descriptor structure.
+ */
+struct dvb_short_smoothing_buffer_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t sb_size : 2; ,
+ uint8_t sb_leak_rate : 6; );
+ /* uint8_t reserved [] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_short_smoothing_buffer_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_short_smoothing_buffer_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_short_smoothing_buffer_descriptor*
+ dvb_short_smoothing_buffer_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct dvb_short_smoothing_buffer_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_short_smoothing_buffer_descriptor*) d;
+}
+
+/**
+ * Accessor for reserved field in a dvb_short_smoothing_buffer_descriptor.
+ *
+ * @param d dvb_short_smoothing_buffer_descriptor pointer.
+ * @return Pointer to reserved field.
+ */
+static inline uint8_t *
+ dvb_short_smoothing_buffer_descriptor_reserved(struct dvb_short_smoothing_buffer_descriptor *d)
+{
+ return (uint8_t*) d + sizeof(struct dvb_short_smoothing_buffer_descriptor);
+}
+
+/**
+ * Calculate length of reserved field in a dvb_short_smoothing_buffer_descriptor.
+ *
+ * @param d dvb_short_smoothing_buffer_descriptor pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ dvb_short_smoothing_buffer_descriptor_reserved_length(struct dvb_short_smoothing_buffer_descriptor *d)
+{
+ return d->d.len - 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/sit_section.c b/lib/libucsi/dvb/sit_section.c
new file mode 100644
index 0000000..06c228c
--- /dev/null
+++ b/lib/libucsi/dvb/sit_section.c
@@ -0,0 +1,69 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/sit_section.h>
+
+struct dvb_sit_section * dvb_sit_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *) ext;
+ struct dvb_sit_section * ret = (struct dvb_sit_section *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct dvb_sit_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+
+ if ((pos + ret->transmission_info_loop_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, ret->transmission_info_loop_length))
+ return NULL;
+
+ pos += ret->transmission_info_loop_length;
+
+ while (pos < len) {
+ struct dvb_sit_service * service = (void*)(buf + pos);
+
+ if ((pos + sizeof(struct dvb_sit_service)) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 2);
+ bswap16(buf + pos + 4);
+ pos += sizeof(struct dvb_sit_service);
+
+ if ((pos + service->service_loop_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, service->service_loop_length))
+ return NULL;
+
+ pos += service->service_loop_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/sit_section.h b/lib/libucsi/dvb/sit_section.h
new file mode 100644
index 0000000..e06d596
--- /dev/null
+++ b/lib/libucsi/dvb/sit_section.h
@@ -0,0 +1,173 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SIT_SECTION_H
+#define _UCSI_DVB_SIT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_sit_section structure.
+ */
+struct dvb_sit_section {
+ struct section_ext head;
+
+ EBIT2(uint16_t reserved : 4; ,
+ uint16_t transmission_info_loop_length :12; );
+ /* struct descriptor descriptors[] */
+ /* struct dvb_sit_service services[] */
+};
+
+/**
+ * An entry in the services field of a dvb_sit_section.
+ */
+struct dvb_sit_service {
+ uint16_t service_id;
+ EBIT3(uint16_t reserved : 1; ,
+ uint16_t running_status : 3; ,
+ uint16_t service_loop_length :12; );
+ /* struct descriptor descriptors[] */
+};
+
+/**
+ * Process a dvb_sit_section.
+ *
+ * @param section Generic section_ext structure.
+ * @return dvb_sit_section pointer, or NULL on error.
+ */
+struct dvb_sit_section * dvb_sit_section_codec(struct section_ext *section);
+
+/**
+ * Iterator for descriptors field in a dvb_sit_section.
+ *
+ * @param sit dvb_sit_section Pointer.
+ * @param pos Variable holding pointer to current descriptor.
+ */
+#define dvb_sit_section_descriptors_for_each(sit, pos) \
+ for ((pos) = dvb_sit_section_descriptors_first(sit); \
+ (pos); \
+ (pos) = dvb_sit_section_descriptors_first(sit))
+
+/**
+ * Iterator for services field in a dvb_sit_section.
+ *
+ * @param sit dvb_sit_section Pointer.
+ * @param pos Variable holding pointer to current dvb_sit_service.
+ */
+#define dvb_sit_section_services_for_each(sit, pos) \
+ for ((pos) = dvb_sit_section_services_first(sit); \
+ (pos); \
+ (pos) = dvb_sit_section_services_next(sit, pos))
+
+/**
+ * Iterator for descriptors field in a dvb_sit_service.
+ *
+ * @param service dvb_sit_service Pointer.
+ * @param pos Variable holding pointer to current descriptor.
+ */
+#define dvb_sit_service_descriptors_for_each(service, pos) \
+ for ((pos) = dvb_sit_service_descriptors_first(service); \
+ (pos); \
+ (pos) = dvb_sit_service_descriptors_next(service, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ dvb_sit_section_descriptors_first(struct dvb_sit_section *sit)
+{
+ if (sit->transmission_info_loop_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) sit + sizeof(struct dvb_sit_section));
+}
+
+static inline struct descriptor *
+ dvb_sit_section_descriptors_next(struct dvb_sit_section *sit,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) sit + sizeof(struct dvb_sit_section),
+ sit->transmission_info_loop_length,
+ pos);
+}
+
+static inline struct dvb_sit_service *
+ dvb_sit_section_services_first(struct dvb_sit_section *sit)
+{
+ size_t pos = sizeof(struct dvb_sit_section) + sit->transmission_info_loop_length;
+
+ if (pos >= section_ext_length(&sit->head))
+ return NULL;
+
+ return (struct dvb_sit_service*) ((uint8_t *) sit + pos);
+}
+
+static inline struct dvb_sit_service *
+ dvb_sit_section_services_next(struct dvb_sit_section *sit,
+ struct dvb_sit_service *pos)
+{
+ uint8_t *end = (uint8_t*) sit + section_ext_length(&sit->head);
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_sit_service) +
+ pos->service_loop_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_sit_service *) next;
+}
+
+static inline struct descriptor *
+ dvb_sit_service_descriptors_first(struct dvb_sit_service * t)
+{
+ if (t->service_loop_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) t + sizeof(struct dvb_sit_service));
+}
+
+static inline struct descriptor *
+ dvb_sit_service_descriptors_next(struct dvb_sit_service *t,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t*) t + sizeof(struct dvb_sit_service),
+ t->service_loop_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/st_section.c b/lib/libucsi/dvb/st_section.c
new file mode 100644
index 0000000..0e60aa1
--- /dev/null
+++ b/lib/libucsi/dvb/st_section.c
@@ -0,0 +1,29 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/st_section.h>
+
+struct dvb_st_section * dvb_st_section_codec(struct section * section)
+{
+ struct dvb_st_section * ret = (struct dvb_st_section *)section;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/st_section.h b/lib/libucsi/dvb/st_section.h
new file mode 100644
index 0000000..52ba888
--- /dev/null
+++ b/lib/libucsi/dvb/st_section.h
@@ -0,0 +1,77 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_ST_SECTION_H
+#define _UCSI_DVB_ST_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * dvb_st_section structure.
+ */
+struct dvb_st_section {
+ struct section head;
+
+ /* uint8_t data[] */
+};
+
+/**
+ * Process a dvb_st_section.
+ *
+ * @param section Generic section header.
+ * @return dvb_st_section pointer, or NULL on error.
+ */
+struct dvb_st_section *dvb_st_section_codec(struct section *section);
+
+/**
+ * Accessor for data field of dvb_st_section.
+ *
+ * @param st dvb_st_section Pointer.
+ * @return Pointer to field.
+ */
+static inline uint8_t*
+ dvb_st_section_data(struct dvb_st_section* st)
+{
+ return (uint8_t*) st + sizeof(struct dvb_st_section);
+}
+
+/**
+ * Calculate length of data field of dvb_st_section.
+ *
+ * @param st dvb_st_section Pointer.
+ * @return Length in bytes.
+ */
+static inline int
+ dvb_st_section_data_length(struct dvb_st_section* st)
+{
+ return st->head.length;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/stream_identifier_descriptor.h b/lib/libucsi/dvb/stream_identifier_descriptor.h
new file mode 100644
index 0000000..262c7e2
--- /dev/null
+++ b/lib/libucsi/dvb/stream_identifier_descriptor.h
@@ -0,0 +1,61 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_STREAM_IDENTIFIER_DESCRIPTOR
+#define _UCSI_DVB_STREAM_IDENTIFIER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_stream_identifier_descriptor structure.
+ */
+struct dvb_stream_identifier_descriptor {
+ struct descriptor d;
+
+ uint8_t component_tag;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_stream_identifier_descriptor.
+ *
+ * @param d Pointer to generic descriptor structure.
+ * @return dvb_stream_identifier_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_stream_identifier_descriptor*
+ dvb_stream_identifier_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_stream_identifier_descriptor) - 2))
+ return NULL;
+
+ return (struct dvb_stream_identifier_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/stuffing_descriptor.h b/lib/libucsi/dvb/stuffing_descriptor.h
new file mode 100644
index 0000000..48e415d
--- /dev/null
+++ b/lib/libucsi/dvb/stuffing_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_STUFFING_DESCRIPTOR
+#define _UCSI_DVB_STUFFING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_stuffing_descriptor.
+ */
+struct dvb_stuffing_descriptor {
+ struct descriptor d;
+
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_stuffing_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_stuffing_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_stuffing_descriptor*
+ dvb_stuffing_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_stuffing_descriptor*) d;
+}
+
+/**
+ * Retrieve a pointer to the data field of a dvb_stuffing_descriptor.
+ *
+ * @param d dvb_stuffing_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ dvb_stuffing_descriptor_data(struct dvb_stuffing_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_stuffing_descriptor);
+}
+
+/**
+ * Calculate length of the data field of a dvb_stuffing_descriptor.
+ *
+ * @param d dvb_stuffing_descriptor pointer.
+ * @return The length in bytes.
+ */
+static inline int
+ dvb_stuffing_descriptor_data_length(struct dvb_stuffing_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/subtitling_descriptor.h b/lib/libucsi/dvb/subtitling_descriptor.h
new file mode 100644
index 0000000..74fc25a
--- /dev/null
+++ b/lib/libucsi/dvb/subtitling_descriptor.h
@@ -0,0 +1,126 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_SUBTITLING_DESCRIPTOR
+#define _UCSI_DVB_SUBTITLING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_subtitling_descriptor structure.
+ */
+struct dvb_subtitling_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_subtitling_entry subtitles[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the subtitles field of the a dvb_subtitling_descriptor.
+ */
+struct dvb_subtitling_entry {
+ iso639lang_t language_code;
+ uint8_t subtitling_type;
+ uint16_t composition_page_id;
+ uint16_t ancillary_page_id;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_subtitling_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_subtitling_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_subtitling_descriptor*
+ dvb_subtitling_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint8_t* ptr = (uint8_t*) d + 2;
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_subtitling_entry))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(ptr+pos+4);
+ bswap16(ptr+pos+6);
+ pos += sizeof(struct dvb_subtitling_entry);
+ }
+
+ return (struct dvb_subtitling_descriptor*) d;
+}
+
+/**
+ * Iterator for subtitles field in dvb_subtitling_descriptor.
+ *
+ * @param d dvb_subtitling_descriptor pointer.
+ * @param pos Variable containing a pointer to current dvb_subtitling_entry.
+ */
+#define dvb_subtitling_descriptor_subtitles_for_each(d, pos) \
+ for ((pos) = dvb_subtitling_descriptor_subtitles_first(d); \
+ (pos); \
+ (pos) = dvb_subtitling_descriptor_subtitles_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_subtitling_entry*
+ dvb_subtitling_descriptor_subtitles_first(struct dvb_subtitling_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_subtitling_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_subtitling_descriptor));
+}
+
+static inline struct dvb_subtitling_entry*
+ dvb_subtitling_descriptor_subtitles_next(struct dvb_subtitling_descriptor *d,
+ struct dvb_subtitling_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_subtitling_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_subtitling_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/target_ip_address_descriptor.h b/lib/libucsi/dvb/target_ip_address_descriptor.h
new file mode 100644
index 0000000..c08b60e
--- /dev/null
+++ b/lib/libucsi/dvb/target_ip_address_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TARGET_IP_ADDRESS_DESCRIPTOR
+#define _UCSI_DVB_TARGET_IP_ADDRESS_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_target_ip_address_descriptor structure.
+ */
+struct dvb_target_ip_address_descriptor {
+ struct descriptor d;
+
+ uint8_t ipv4_addr_mask[4];
+ /* struct dvb_ipv4_addr ipv4_addr[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ipv4_addr field of a dvb_target_ip_address_descriptor.
+ */
+struct dvb_ipv4_addr {
+ uint8_t ipv4_addr[4];
+} __ucsi_packed;
+
+/**
+ * Process a dvb_target_ip_address_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_target_ip_address_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_target_ip_address_descriptor*
+ dvb_target_ip_address_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len - 4;
+
+ if (len % sizeof(struct dvb_ipv4_addr))
+ return NULL;
+
+ return (struct dvb_target_ip_address_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ipv4_addr field of a dvb_target_ip_address_descriptor.
+ *
+ * @param d dvb_target_ip_address_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ipv4_addr.
+ */
+#define dvb_target_ip_address_descriptor_ipv4_addr_for_each(d, pos) \
+ for ((pos) = dvb_target_ip_address_descriptor_ipv4_addr_first(d); \
+ (pos); \
+ (pos) = dvb_target_ip_address_descriptor_ipv4_addr_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ipv4_addr*
+ dvb_target_ip_address_descriptor_ipv4_addr_first(struct dvb_target_ip_address_descriptor *d)
+{
+ if (d->d.len == 4)
+ return NULL;
+
+ return (struct dvb_ipv4_addr *)
+ ((uint8_t*) d + sizeof(struct dvb_target_ip_address_descriptor));
+}
+
+static inline struct dvb_ipv4_addr*
+ dvb_target_ip_address_descriptor_ipv4_addr_next(struct dvb_target_ip_address_descriptor *d,
+ struct dvb_ipv4_addr *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len - 4;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv4_addr);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ipv4_addr *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/target_ip_slash_descriptor.h b/lib/libucsi/dvb/target_ip_slash_descriptor.h
new file mode 100644
index 0000000..e5bc76a
--- /dev/null
+++ b/lib/libucsi/dvb/target_ip_slash_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TARGET_IP_SLASH_DESCRIPTOR
+#define _UCSI_DVB_TARGET_IP_SLASH_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_target_ip_slash_descriptor structure.
+ */
+struct dvb_target_ip_slash_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_ipv4_slash ipv4_slash[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ipv4_slash field of a dvb_target_ip_slash_descriptor.
+ */
+struct dvb_ipv4_slash {
+ uint8_t ipv4_addr[4];
+ uint8_t ipv4_slash;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_target_ip_slash_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_target_ip_slash_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_target_ip_slash_descriptor*
+ dvb_target_ip_slash_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_ipv4_slash))
+ return NULL;
+
+ return (struct dvb_target_ip_slash_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ipv4_slash field of a dvb_target_ip_slash_descriptor.
+ *
+ * @param d dvb_target_ip_slash_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ipv4_slash.
+ */
+#define dvb_target_ip_slash_descriptor_ipv4_slash_for_each(d, pos) \
+ for ((pos) = dvb_target_ip_slash_descriptor_ipv4_slash_first(d); \
+ (pos); \
+ (pos) = dvb_target_ip_slash_descriptor_ipv4_slash_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ipv4_slash*
+ dvb_target_ip_slash_descriptor_ipv4_slash_first(struct dvb_target_ip_slash_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_ipv4_slash *)
+ ((uint8_t*) d + sizeof(struct dvb_target_ip_slash_descriptor));
+}
+
+static inline struct dvb_ipv4_slash*
+ dvb_target_ip_slash_descriptor_ipv4_slash_next(struct dvb_target_ip_slash_descriptor *d,
+ struct dvb_ipv4_slash *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv4_slash);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ipv4_slash *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/target_ip_source_slash_descriptor.h b/lib/libucsi/dvb/target_ip_source_slash_descriptor.h
new file mode 100644
index 0000000..8cade48
--- /dev/null
+++ b/lib/libucsi/dvb/target_ip_source_slash_descriptor.h
@@ -0,0 +1,118 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TARGET_IP_SOURCE_SLASH_DESCRIPTOR
+#define _UCSI_DVB_TARGET_IP_SOURCE_SLASH_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_target_ip_source_slash_descriptor structure.
+ */
+struct dvb_target_ip_source_slash_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_ipv4_source_slash ipv4_source_slash[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ipv4_source_slash field of a dvb_target_ip_source_slash_descriptor.
+ */
+struct dvb_ipv4_source_slash {
+ uint8_t ipv4_source_addr[4];
+ uint8_t ipv4_source_slash;
+ uint8_t ipv4_dest_addr[4];
+ uint8_t ipv4_dest_slash;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_target_ip_source_slash_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_target_ip_source_slash_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_target_ip_source_slash_descriptor*
+ dvb_target_ip_source_slash_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_ipv4_source_slash))
+ return NULL;
+
+ return (struct dvb_target_ip_source_slash_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ipv4_source_slash field of a dvb_target_ip_source_slash_descriptor.
+ *
+ * @param d dvb_target_ip_source_slash_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ipv4_source_slash.
+ */
+#define dvb_target_ip_source_slash_descriptor_ipv4_source_slash_for_each(d, pos) \
+ for ((pos) = dvb_target_ip_source_slash_descriptor_ipv4_source_slash_first(d); \
+ (pos); \
+ (pos) = dvb_target_ip_source_slash_descriptor_ipv4_source_slash_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ipv4_source_slash*
+ dvb_target_ip_source_slash_descriptor_ipv4_source_slash_first(struct dvb_target_ip_source_slash_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_ipv4_source_slash *)
+ ((uint8_t*) d + sizeof(struct dvb_target_ip_source_slash_descriptor));
+}
+
+static inline struct dvb_ipv4_source_slash*
+ dvb_target_ip_source_slash_descriptor_ipv4_source_slash_next(struct dvb_target_ip_source_slash_descriptor *d,
+ struct dvb_ipv4_source_slash *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv4_source_slash);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ipv4_source_slash *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/target_ipv6_address_descriptor.h b/lib/libucsi/dvb/target_ipv6_address_descriptor.h
new file mode 100644
index 0000000..1b28b48
--- /dev/null
+++ b/lib/libucsi/dvb/target_ipv6_address_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TARGET_IPV6_ADDRESS_DESCRIPTOR
+#define _UCSI_DVB_TARGET_IPV6_ADDRESS_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_target_ipv6_address_descriptor structure.
+ */
+struct dvb_target_ipv6_address_descriptor {
+ struct descriptor d;
+
+ uint8_t ipv6_addr_mask[16];
+ /* struct dvb_ipv6_addr ipv6_addr[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ipv6_addr field of a dvb_target_ipv6_address_descriptor.
+ */
+struct dvb_ipv6_addr {
+ uint8_t ipv6_addr[16];
+} __ucsi_packed;
+
+/**
+ * Process a dvb_target_ipv6_address_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_target_ipv6_address_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_target_ipv6_address_descriptor*
+ dvb_target_ipv6_address_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len - 16;
+
+ if (len % sizeof(struct dvb_ipv6_addr))
+ return NULL;
+
+ return (struct dvb_target_ipv6_address_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ipv6_addr field of a dvb_target_ipv6_address_descriptor.
+ *
+ * @param d dvb_target_ipv6_address_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ipv6_addr.
+ */
+#define dvb_target_ipv6_address_descriptor_ipv6_addr_for_each(d, pos) \
+ for ((pos) = dvb_target_ipv6_address_descriptor_ipv6_addr_first(d); \
+ (pos); \
+ (pos) = dvb_target_ipv6_address_descriptor_ipv6_addr_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ipv6_addr*
+ dvb_target_ipv6_address_descriptor_ipv6_addr_first(struct dvb_target_ipv6_address_descriptor *d)
+{
+ if (d->d.len == 16)
+ return NULL;
+
+ return (struct dvb_ipv6_addr *)
+ ((uint8_t*) d + sizeof(struct dvb_target_ipv6_address_descriptor));
+}
+
+static inline struct dvb_ipv6_addr*
+ dvb_target_ipv6_address_descriptor_ipv6_addr_next(struct dvb_target_ipv6_address_descriptor *d,
+ struct dvb_ipv6_addr *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len - 16;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv6_addr);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ipv6_addr *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/target_ipv6_slash_descriptor.h b/lib/libucsi/dvb/target_ipv6_slash_descriptor.h
new file mode 100644
index 0000000..3dc6d75
--- /dev/null
+++ b/lib/libucsi/dvb/target_ipv6_slash_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TARGET_IPV6_SLASH_DESCRIPTOR
+#define _UCSI_DVB_TARGET_IPV6_SLASH_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_target_ipv6_slash_descriptor structure.
+ */
+struct dvb_target_ipv6_slash_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_ipv6_slash ipv6_slash[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ipv6_slash field of a dvb_target_ipv6_slash_descriptor.
+ */
+struct dvb_ipv6_slash {
+ uint8_t ipv6_addr[16];
+ uint8_t ipv6_slash;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_target_ipv6_slash_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_target_ipv6_slash_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_target_ipv6_slash_descriptor*
+ dvb_target_ipv6_slash_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_ipv6_slash))
+ return NULL;
+
+ return (struct dvb_target_ipv6_slash_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ipv6_slash field of a dvb_target_ipv6_slash_descriptor.
+ *
+ * @param d dvb_target_ipv6_slash_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ipv6_slash.
+ */
+#define dvb_target_ipv6_slash_descriptor_ipv6_slash_for_each(d, pos) \
+ for ((pos) = dvb_target_ipv6_slash_descriptor_ipv6_slash_first(d); \
+ (pos); \
+ (pos) = dvb_target_ipv6_slash_descriptor_ipv6_slash_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ipv6_slash*
+ dvb_target_ipv6_slash_descriptor_ipv6_slash_first(struct dvb_target_ipv6_slash_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_ipv6_slash *)
+ ((uint8_t*) d + sizeof(struct dvb_target_ipv6_slash_descriptor));
+}
+
+static inline struct dvb_ipv6_slash*
+ dvb_target_ipv6_slash_descriptor_ipv6_slash_next(struct dvb_target_ipv6_slash_descriptor *d,
+ struct dvb_ipv6_slash *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv6_slash);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ipv6_slash *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/target_ipv6_source_slash_descriptor.h b/lib/libucsi/dvb/target_ipv6_source_slash_descriptor.h
new file mode 100644
index 0000000..3a4b38e
--- /dev/null
+++ b/lib/libucsi/dvb/target_ipv6_source_slash_descriptor.h
@@ -0,0 +1,118 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TARGET_IPV6_SOURCE_SLASH_DESCRIPTOR
+#define _UCSI_DVB_TARGET_IPV6_SOURCE_SLASH_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_target_ipv6_source_slash_descriptor structure.
+ */
+struct dvb_target_ipv6_source_slash_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_ipv6_source_slash ipv6_source_slash[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the ipv6_source_slash field of a dvb_target_ipv6_source_slash_descriptor.
+ */
+struct dvb_ipv6_source_slash {
+ uint8_t ipv6_source_addr[16];
+ uint8_t ipv6_source_slash;
+ uint8_t ipv6_dest_addr[16];
+ uint8_t ipv6_dest_slash;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_target_ipv6_source_slash_descriptor.
+ *
+ * @param d Generic descriptor structure pointer.
+ * @return dvb_target_ipv6_source_slash_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_target_ipv6_source_slash_descriptor*
+ dvb_target_ipv6_source_slash_descriptor_codec(struct descriptor* d)
+{
+ uint32_t len = d->len;
+
+ if (len % sizeof(struct dvb_ipv6_source_slash))
+ return NULL;
+
+ return (struct dvb_target_ipv6_source_slash_descriptor*) d;
+}
+
+/**
+ * Iterator for entries in the ipv6_source_slash field of a dvb_target_ipv6_source_slash_descriptor.
+ *
+ * @param d dvb_target_ipv6_source_slash_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_ipv6_source_slash.
+ */
+#define dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_for_each(d, pos) \
+ for ((pos) = dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_first(d); \
+ (pos); \
+ (pos) = dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_ipv6_source_slash*
+ dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_first(struct dvb_target_ipv6_source_slash_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_ipv6_source_slash *)
+ ((uint8_t*) d + sizeof(struct dvb_target_ipv6_source_slash_descriptor));
+}
+
+static inline struct dvb_ipv6_source_slash*
+ dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_next(struct dvb_target_ipv6_source_slash_descriptor *d,
+ struct dvb_ipv6_source_slash *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv6_source_slash);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_ipv6_source_slash *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/tdt_section.c b/lib/libucsi/dvb/tdt_section.c
new file mode 100644
index 0000000..ba64fe9
--- /dev/null
+++ b/lib/libucsi/dvb/tdt_section.c
@@ -0,0 +1,33 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/tdt_section.h>
+
+struct dvb_tdt_section * dvb_tdt_section_codec(struct section * section)
+{
+ size_t len = section_length(section);
+ struct dvb_tdt_section * ret = (struct dvb_tdt_section *) section;
+
+ if (len != sizeof(struct dvb_tdt_section))
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/tdt_section.h b/lib/libucsi/dvb/tdt_section.h
new file mode 100644
index 0000000..fc2bcb8
--- /dev/null
+++ b/lib/libucsi/dvb/tdt_section.h
@@ -0,0 +1,54 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TDT_SECTION_H
+#define _UCSI_DVB_TDT_SECTION_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+#include <libucsi/dvb/types.h>
+
+/**
+ * dvb_tdt_section structure.
+ */
+struct dvb_tdt_section {
+ struct section head;
+
+ dvbdate_t utc_time;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_tdt_section.
+ *
+ * @param section Generic section header.
+ * @return dvb_tdt_section pointer, or NULL on error.
+ */
+struct dvb_tdt_section *dvb_tdt_section_codec(struct section *section);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/telephone_descriptor.h b/lib/libucsi/dvb/telephone_descriptor.h
new file mode 100644
index 0000000..3dc43a1
--- /dev/null
+++ b/lib/libucsi/dvb/telephone_descriptor.h
@@ -0,0 +1,150 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TELEPHONE_DESCRIPTOR
+#define _UCSI_DVB_TELEPHONE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_telephone_descriptor stucture.
+ */
+struct dvb_telephone_descriptor {
+ struct descriptor d;
+
+ EBIT3(uint8_t reserved_1 : 2; ,
+ uint8_t foreign_availability : 1; ,
+ uint8_t connection_type : 5; );
+ EBIT4(uint8_t reserved_2 : 1; ,
+ uint8_t country_prefix_length : 2; ,
+ uint8_t international_area_code_length : 3; ,
+ uint8_t operator_code_length : 2; );
+ EBIT3(uint8_t reserved_3 : 1; ,
+ uint8_t national_area_code_length : 3; ,
+ uint8_t core_number_length : 4; );
+ /* uint8_t country_prefix[] */
+ /* uint8_t international_area_code[] */
+ /* uint8_t operator_code[] */
+ /* uint8_t national_area_code[] */
+ /* uint8_t core_number[] */
+} __ucsi_packed;
+
+
+/**
+ * Process a dvb_telephone_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_telephone_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_telephone_descriptor*
+ dvb_telephone_descriptor_codec(struct descriptor* d)
+{
+ struct dvb_telephone_descriptor* p =
+ (struct dvb_telephone_descriptor*) d;
+ uint32_t pos = sizeof(struct dvb_telephone_descriptor) - 2;
+ uint32_t len = d->len;
+
+ if (pos > len)
+ return NULL;
+
+ pos += p->country_prefix_length +
+ p->international_area_code_length +
+ p->operator_code_length +
+ p->national_area_code_length +
+ p->core_number_length;
+
+ if (pos != len)
+ return NULL;
+
+ return p;
+}
+
+/**
+ * Retrieve pointer to country_prefix field of a dvb_telephone_descriptor.
+ *
+ * @param d dvb_telephone_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_telephone_descriptor_country_prefix(struct dvb_telephone_descriptor* d)
+{
+ return (uint8_t*) d + sizeof(struct dvb_telephone_descriptor);
+}
+
+/**
+ * Retrieve pointer to international_area_code field of a dvb_telephone_descriptor.
+ *
+ * @param d dvb_telephone_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_telephone_descriptor_international_area_code(struct dvb_telephone_descriptor* d)
+{
+ return dvb_telephone_descriptor_country_prefix(d) + d->country_prefix_length;
+}
+
+/**
+ * Retrieve pointer to operator_code field of a dvb_telephone_descriptor.
+ *
+ * @param d dvb_telephone_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_telephone_descriptor_operator_code(struct dvb_telephone_descriptor* d)
+{
+ return dvb_telephone_descriptor_international_area_code(d) + d->international_area_code_length;
+}
+
+/**
+ * Retrieve pointer to national_area_code field of a dvb_telephone_descriptor.
+ *
+ * @param d dvb_telephone_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_telephone_descriptor_national_area_code(struct dvb_telephone_descriptor* d)
+{
+ return dvb_telephone_descriptor_operator_code(d) + d->operator_code_length;
+}
+
+/**
+ * Retrieve pointer to core_number field of a dvb_telephone_descriptor.
+ *
+ * @param d dvb_telephone_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ dvb_telephone_descriptor_core_number(struct dvb_telephone_descriptor* d)
+{
+ return dvb_telephone_descriptor_national_area_code(d) + d->national_area_code_length;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/teletext_descriptor.h b/lib/libucsi/dvb/teletext_descriptor.h
new file mode 100644
index 0000000..424c1cb
--- /dev/null
+++ b/lib/libucsi/dvb/teletext_descriptor.h
@@ -0,0 +1,127 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TELETEXT_DESCRIPTOR
+#define _UCSI_DVB_TELETEXT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * Possible values for the type field.
+ */
+enum {
+ DVB_TELETEXT_TYPE_INITIAL = 0x01,
+ DVB_TELETEXT_TYPE_SUBTITLE = 0x02,
+ DVB_TELETEXT_TYPE_ADDITIONAL = 0x03,
+ DVB_TELETEXT_TYPE_SCHEDULE = 0x04,
+ DVB_TELETEXT_TYPE_SUBTITLE_HEARING_IMPAIRED= 0x05,
+};
+
+/**
+ * dvb_teletext_descriptor structure.
+ */
+struct dvb_teletext_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_teletext_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a dvb_teletext_descriptor.
+ */
+struct dvb_teletext_entry {
+ iso639lang_t language_code;
+ EBIT2(uint8_t type : 5; ,
+ uint8_t magazine_number: 3; );
+ uint8_t page_number;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_teletext_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_teletext_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_teletext_descriptor*
+ dvb_teletext_descriptor_codec(struct descriptor* d)
+{
+ if (d->len % sizeof(struct dvb_teletext_entry))
+ return NULL;
+
+ return (struct dvb_teletext_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field of a dvb_teletext_descriptor.
+ *
+ * @param d dvb_teletext_descriptor pointer.
+ * @param pos Variable holding a pointer to the current dvb_teletext_entry.
+ */
+#define dvb_teletext_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_teletext_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_teletext_descriptor_entries_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_teletext_entry*
+ dvb_teletext_descriptor_entries_first(struct dvb_teletext_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_teletext_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_teletext_descriptor));
+}
+
+static inline struct dvb_teletext_entry*
+ dvb_teletext_descriptor_entries_next(struct dvb_teletext_descriptor *d,
+ struct dvb_teletext_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_teletext_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_teletext_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/terrestrial_delivery_descriptor.h b/lib/libucsi/dvb/terrestrial_delivery_descriptor.h
new file mode 100644
index 0000000..c624dab
--- /dev/null
+++ b/lib/libucsi/dvb/terrestrial_delivery_descriptor.h
@@ -0,0 +1,77 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TERRESTRIAL_DELIVERY_DESCRIPTOR
+#define _UCSI_DVB_TERRESTRIAL_DELIVERY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_terrestrial_delivery_descriptor structure.
+ */
+struct dvb_terrestrial_delivery_descriptor {
+ struct descriptor d;
+
+ uint32_t centre_frequency; // Normal integer, units 10Hz
+ EBIT5(uint8_t bandwidth : 3; ,
+ uint8_t priority : 1; ,
+ uint8_t time_slicing_indicator : 1; ,
+ uint8_t mpe_fec_indicator : 1; ,
+ uint8_t reserved_1 : 2; );
+ EBIT3(uint8_t constellation : 2; ,
+ uint8_t hierarchy_information : 3; ,
+ uint8_t code_rate_hp_stream : 3; );
+ EBIT4(uint8_t code_rate_lp_stream : 3; ,
+ uint8_t guard_interval : 2; ,
+ uint8_t transmission_mode : 2; ,
+ uint8_t other_frequency_flag : 1; );
+ uint32_t reserved_2;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_terrestrial_delivery_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_terrestrial_delivery_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_terrestrial_delivery_descriptor*
+ dvb_terrestrial_delivery_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_terrestrial_delivery_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+ bswap32((uint8_t*) d + 9);
+
+ return (struct dvb_terrestrial_delivery_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/time_shifted_event_descriptor.h b/lib/libucsi/dvb/time_shifted_event_descriptor.h
new file mode 100644
index 0000000..6b4a9f6
--- /dev/null
+++ b/lib/libucsi/dvb/time_shifted_event_descriptor.h
@@ -0,0 +1,65 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TIME_SHIFTED_EVENT_DESCRIPTOR
+#define _UCSI_DVB_TIME_SHIFTED_EVENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_time_shifted_event_descriptor structure.
+ */
+struct dvb_time_shifted_event_descriptor {
+ struct descriptor d;
+
+ uint16_t reference_service_id;
+ uint16_t reference_event_id;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_time_shifted_event_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_time_shifted_event_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_time_shifted_event_descriptor*
+ dvb_time_shifted_event_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_time_shifted_event_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+ bswap16((uint8_t*) d + 4);
+
+ return (struct dvb_time_shifted_event_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/time_shifted_service_descriptor.h b/lib/libucsi/dvb/time_shifted_service_descriptor.h
new file mode 100644
index 0000000..c8dcc0e
--- /dev/null
+++ b/lib/libucsi/dvb/time_shifted_service_descriptor.h
@@ -0,0 +1,63 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TIME_SHIFTED_SERVICE_DESCRIPTOR
+#define _UCSI_DVB_TIME_SHIFTED_SERVICE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_time_shifted_service_descriptor structure.
+ */
+struct dvb_time_shifted_service_descriptor {
+ struct descriptor d;
+
+ uint16_t reference_service_id;
+} __ucsi_packed;
+
+/**
+ * Process a dvb_time_shifted_service_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return Pointer to dvb_time_shifted_service_descriptor, or NULL on error.
+ */
+static inline struct dvb_time_shifted_service_descriptor*
+ dvb_time_shifted_service_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct dvb_time_shifted_service_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+
+ return (struct dvb_time_shifted_service_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/tot_section.c b/lib/libucsi/dvb/tot_section.c
new file mode 100644
index 0000000..5dc7890
--- /dev/null
+++ b/lib/libucsi/dvb/tot_section.c
@@ -0,0 +1,50 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/tot_section.h>
+
+struct dvb_tot_section *dvb_tot_section_codec(struct section *section)
+{
+ uint8_t * buf = (uint8_t *)section;
+ size_t pos = sizeof(struct section);
+ size_t len = section_length(section) - CRC_SIZE;
+ struct dvb_tot_section * ret = (struct dvb_tot_section *)section;
+
+ if (len < sizeof(struct dvb_tot_section))
+ return NULL;
+
+ pos += 5;
+ bswap16(buf + pos);
+ pos += 2;
+
+ if ((pos + ret->descriptors_loop_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, ret->descriptors_loop_length))
+ return NULL;
+
+ pos += ret->descriptors_loop_length;
+
+ if (pos != len)
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/tot_section.h b/lib/libucsi/dvb/tot_section.h
new file mode 100644
index 0000000..3474da1
--- /dev/null
+++ b/lib/libucsi/dvb/tot_section.h
@@ -0,0 +1,97 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TOT_SECTION_H
+#define _UCSI_DVB_TOT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+#include <libucsi/dvb/types.h>
+
+/**
+ * dvb_tot_section structure.
+ */
+struct dvb_tot_section {
+ struct section head;
+
+ dvbdate_t utc_time;
+ EBIT2(uint16_t reserved : 4; ,
+ uint16_t descriptors_loop_length:12; );
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_tot_section.
+ *
+ * @param section Pointer to generic section structure.
+ * @return dvb_tot_section pointer, or NULL on error.
+ */
+struct dvb_tot_section * dvb_tot_section_codec(struct section *section);
+
+/**
+ * Iterator for descriptors field of dvb_tot_section.
+ *
+ * @param tot dvb_tot_section pointer.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define dvb_tot_section_descriptors_for_each(tot, pos) \
+ for ((pos) = dvb_tot_section_descriptors_first(tot); \
+ (pos); \
+ (pos) = dvb_tot_section_descriptors_next(tot, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ dvb_tot_section_descriptors_first(struct dvb_tot_section * tot)
+{
+ if (tot->descriptors_loop_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) tot + sizeof(struct dvb_tot_section));
+}
+
+static inline struct descriptor *
+ dvb_tot_section_descriptors_next(struct dvb_tot_section *tot,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t *) tot + sizeof(struct dvb_tot_section),
+ tot->descriptors_loop_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/transport_stream_descriptor.h b/lib/libucsi/dvb/transport_stream_descriptor.h
new file mode 100644
index 0000000..1797ec5
--- /dev/null
+++ b/lib/libucsi/dvb/transport_stream_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TRANSPORT_STREAM_DESCRIPTOR
+#define _UCSI_DVB_TRANSPORT_STREAM_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_transport_stream_descriptor structure.
+ */
+struct dvb_transport_stream_descriptor {
+ struct descriptor d;
+
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process dvb_transport_stream_descriptor structure.
+ *
+ * @param d Pointer to generic descriptor.
+ * @return dvb_transport_stream_descriptor structure or NULL on error.
+ */
+static inline struct dvb_transport_stream_descriptor*
+ dvb_transport_stream_descriptor_codec(struct descriptor* d)
+{
+ return (struct dvb_transport_stream_descriptor*) d;
+}
+
+/**
+ * Retrieve a pointer to the data field of a dvb_transport_stream_descriptor.
+ *
+ * @param d dvb_transport_stream_descriptor structure.
+ * @return Pointer to data field.
+ */
+static inline uint8_t *
+ dvb_transport_stream_descriptor_data(struct dvb_transport_stream_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_transport_stream_descriptor);
+}
+
+/**
+ * Calculate the length of the data field of a dvb_transport_stream_descriptor.
+ *
+ * @param d dvb_transport_stream_descriptor structure.
+ * @return length of data field in bytes.
+ */
+static inline int
+ dvb_transport_stream_descriptor_data_length(struct dvb_transport_stream_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/tva_container_section.c b/lib/libucsi/dvb/tva_container_section.c
new file mode 100644
index 0000000..f526efc
--- /dev/null
+++ b/lib/libucsi/dvb/tva_container_section.c
@@ -0,0 +1,33 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/dvb/tva_container_section.h>
+
+struct dvb_tva_container_section *dvb_tva_container_section_codec(struct section_ext *ext)
+{
+ size_t len = section_ext_length(ext);
+ struct dvb_tva_container_section* ret = (struct dvb_tva_container_section*) ext;
+
+ if (len < sizeof(struct dvb_tva_container_section))
+ return NULL;
+
+ return ret;
+}
diff --git a/lib/libucsi/dvb/tva_container_section.h b/lib/libucsi/dvb/tva_container_section.h
new file mode 100644
index 0000000..7d0abb1
--- /dev/null
+++ b/lib/libucsi/dvb/tva_container_section.h
@@ -0,0 +1,90 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TVA_CONTAINER_SECTION_H
+#define _UCSI_DVB_TVA_CONTAINER_SECTION_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+#include <libucsi/dvb/types.h>
+
+/**
+ * dvb_tva_container_section structure.
+ */
+struct dvb_tva_container_section {
+ struct section_ext head;
+
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process a dvb_tva_container_section.
+ *
+ * @param section Generic section header.
+ * @return dvb_tdt_section pointer, or NULL on error.
+ */
+struct dvb_tva_container_section *dvb_tva_container_section_codec(struct section_ext *ext);
+
+/**
+ * Accessor for the container_id field of a tva container section.
+ *
+ * @param container dvb_tva_container_section pointer.
+ * @return The container_id.
+ */
+static inline uint16_t dvb_tva_container_section_container_id(struct dvb_tva_container_section *container)
+{
+ return container->head.table_id_ext;
+}
+
+/**
+ * Accessor for the data field of a dvb_data_broadcast_id_descriptor.
+ *
+ * @param d dvb_data_broadcast_id_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+dvb_tva_container_section_data(struct dvb_tva_container_section *s)
+{
+ return (uint8_t *) s + sizeof(struct dvb_tva_container_section);
+}
+
+/**
+ * Determine the number of bytes in the data field of a dvb_tva_container_section.
+ *
+ * @param d dvb_tva_container_section pointer.
+ * @return Length of the field in bytes.
+ */
+static inline int
+dvb_tva_container_section_data_length(struct dvb_tva_container_section *s)
+{
+ return section_ext_length(&s->head) - sizeof(struct dvb_tva_container_section);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/tva_id_descriptor.h b/lib/libucsi/dvb/tva_id_descriptor.h
new file mode 100644
index 0000000..3b4f3e8
--- /dev/null
+++ b/lib/libucsi/dvb/tva_id_descriptor.h
@@ -0,0 +1,124 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TVA_ID_DESCRIPTOR
+#define _UCSI_DVB_TVA_ID_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * dvb_tva_id_descriptor structure.
+ */
+struct dvb_tva_id_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_tva_id_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the entries field of a dvb_tva_id_descriptor.
+ */
+struct dvb_tva_id_entry {
+ uint16_t tva_id;
+ EBIT2(uint8_t reserved : 5; ,
+ uint8_t running_status : 3; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_tva_id_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return dvb_tva_id_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_tva_id_descriptor*
+ dvb_tva_id_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+ uint8_t* buf = (uint8_t*) d + 2;
+
+ pos += sizeof(struct dvb_tva_id_descriptor) - 2;
+ if (len % sizeof(struct dvb_tva_id_entry))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ pos+=3;
+ }
+
+ return (struct dvb_tva_id_descriptor*) d;
+}
+
+/**
+ * Iterator for the entries field of a dvb_tva_id_descriptor.
+ *
+ * @param d dvb_tva_id_descriptor pointer.
+ * @param pos Variable containing a pointer to the current dvb_tva_id_entry.
+ */
+#define dvb_tva_id_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_tva_id_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_tva_id_descriptor_entries_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_tva_id_entry*
+ dvb_tva_id_descriptor_entries_first(struct dvb_tva_id_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_tva_id_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_tva_id_descriptor));
+}
+
+static inline struct dvb_tva_id_entry*
+ dvb_tva_id_descriptor_entries_next(struct dvb_tva_id_descriptor *d,
+ struct dvb_tva_id_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_tva_id_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_tva_id_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/types.c b/lib/libucsi/dvb/types.c
new file mode 100644
index 0000000..c1cf583
--- /dev/null
+++ b/lib/libucsi/dvb/types.c
@@ -0,0 +1,270 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <string.h>
+#include "types.h"
+
+time_t dvbdate_to_unixtime(dvbdate_t dvbdate)
+{
+ int k = 0;
+ struct tm tm;
+ double mjd;
+
+ /* check for the undefined value */
+ if ((dvbdate[0] == 0xff) &&
+ (dvbdate[1] == 0xff) &&
+ (dvbdate[2] == 0xff) &&
+ (dvbdate[3] == 0xff) &&
+ (dvbdate[4] == 0xff)) {
+ return -1;
+ }
+
+ memset(&tm, 0, sizeof(tm));
+ mjd = (dvbdate[0] << 8) | dvbdate[1];
+
+ tm.tm_year = (int) ((mjd - 15078.2) / 365.25);
+ tm.tm_mon = (int) (((mjd - 14956.1) - (int) (tm.tm_year * 365.25)) / 30.6001);
+ tm.tm_mday = (int) mjd - 14956 - (int) (tm.tm_year * 365.25) - (int) (tm.tm_mon * 30.6001);
+ if ((tm.tm_mon == 14) || (tm.tm_mon == 15)) k = 1;
+ tm.tm_year += k;
+ tm.tm_mon = tm.tm_mon - 2 - k * 12;
+ tm.tm_sec = bcd_to_integer(dvbdate[4]);
+ tm.tm_min = bcd_to_integer(dvbdate[3]);
+ tm.tm_hour = bcd_to_integer(dvbdate[2]);
+
+ return mktime(&tm);
+}
+
+void unixtime_to_dvbdate(time_t unixtime, dvbdate_t dvbdate)
+{
+ struct tm tm;
+ double l = 0;
+ int mjd;
+
+ /* the undefined value */
+ if (unixtime == -1) {
+ memset(dvbdate, 0xff, 5);
+ return;
+ }
+
+ gmtime_r(&unixtime, &tm);
+ tm.tm_mon++;
+ if ((tm.tm_mon == 1) || (tm.tm_mon == 2)) l = 1;
+ mjd = 14956 + tm.tm_mday + (int) ((tm.tm_year - l) * 365.25) + (int) ((tm.tm_mon + 1 + l * 12) * 30.6001);
+
+ dvbdate[0] = (mjd & 0xff00) >> 8;
+ dvbdate[1] = mjd & 0xff;
+ dvbdate[2] = integer_to_bcd(tm.tm_hour);
+ dvbdate[3] = integer_to_bcd(tm.tm_min);
+ dvbdate[4] = integer_to_bcd(tm.tm_sec);
+}
+
+int dvbduration_to_seconds(dvbduration_t dvbduration)
+{
+ int seconds = 0;
+
+ seconds += (bcd_to_integer(dvbduration[0]) * 60 * 60);
+ seconds += (bcd_to_integer(dvbduration[1]) * 60);
+ seconds += bcd_to_integer(dvbduration[2]);
+
+ return seconds;
+}
+
+void seconds_to_dvbduration(int seconds, dvbduration_t dvbduration)
+{
+ int hours, mins;
+
+ hours = seconds / (60*60);
+ seconds -= (hours * 60 * 60);
+ mins = seconds / 60;
+ seconds -= (mins * 60);
+
+ dvbduration[0] = integer_to_bcd(hours);
+ dvbduration[1] = integer_to_bcd(mins);
+ dvbduration[2] = integer_to_bcd(seconds);
+}
+
+int dvbhhmm_to_seconds(dvbhhmm_t dvbhhmm)
+{
+ int seconds = 0;
+
+ seconds += (bcd_to_integer(dvbhhmm[0]) * 60 * 60);
+ seconds += (bcd_to_integer(dvbhhmm[1]) * 60);
+
+ return seconds;
+}
+
+void seconds_to_dvbhhmm(int seconds, dvbhhmm_t dvbhhmm)
+{
+ int hours, mins;
+
+ hours = seconds / (60*60);
+ seconds -= (hours * 60 * 60);
+ mins = seconds / 60;
+
+ dvbhhmm[0] = integer_to_bcd(hours);
+ dvbhhmm[1] = integer_to_bcd(mins);
+}
+
+uint32_t integer_to_bcd(uint32_t intval)
+{
+ uint32_t val = 0;
+
+ int i;
+ for(i=0; i<=28;i+=4) {
+ val |= ((intval % 10) << i);
+ intval /= 10;
+ }
+
+ return val;
+}
+
+uint32_t bcd_to_integer(uint32_t bcdval)
+{
+ uint32_t val = 0;
+
+ int i;
+ for(i=28; i>=0;i-=4) {
+ val += ((bcdval >> i) & 0x0f);
+ if (i != 0) val *= 10;
+ }
+
+ return val;
+}
+
+const char *dvb_charset(char *dvb_text, int dvb_text_length, int *consumed)
+{
+ char *charset = "ISO6937";
+ int used = 0;
+
+ if (dvb_text_length == 0)
+ goto exit;
+ if (dvb_text[0] >= 32)
+ goto exit;
+ if (dvb_text[0] == 0x10) {
+ if (dvb_text_length < 3)
+ goto exit;
+
+ used = 3;
+ uint16_t ext = (dvb_text[1] << 8) | dvb_text[2];
+ switch(ext) {
+ case 0x01:
+ charset = "ISO8859-1";
+ break;
+ case 0x02:
+ charset = "ISO8859-2";
+ break;
+ case 0x03:
+ charset = "ISO8859-3";
+ break;
+ case 0x04:
+ charset = "ISO8859-4";
+ break;
+ case 0x05:
+ charset = "ISO8859-5";
+ break;
+ case 0x06:
+ charset = "ISO8859-6";
+ break;
+ case 0x07:
+ charset = "ISO8859-7";
+ break;
+ case 0x08:
+ charset = "ISO8859-8";
+ break;
+ case 0x09:
+ charset = "ISO8859-9";
+ break;
+ case 0x0a:
+ charset = "ISO8859-10";
+ break;
+ case 0x0b:
+ charset = "ISO8859-11";
+ break;
+ case 0x0d:
+ charset = "ISO8859-13";
+ break;
+ case 0x0e:
+ charset = "ISO8859-14";
+ break;
+ case 0x0f:
+ charset = "ISO8859-15";
+ break;
+ default:
+ used = 0;
+ break;
+ }
+ } else {
+ used = 1;
+ switch(dvb_text[0]) {
+ case 0x01:
+ charset = "ISO8859-5";
+ break;
+ case 0x02:
+ charset = "ISO8859-6";
+ break;
+ case 0x03:
+ charset = "ISO8859-7";
+ break;
+ case 0x04:
+ charset = "ISO8859-8";
+ break;
+ case 0x05:
+ charset = "ISO8859-9";
+ break;
+ case 0x06:
+ charset = "ISO8859-10";
+ break;
+ case 0x07:
+ charset = "ISO8859-11";
+ break;
+ case 0x09:
+ charset = "ISO8859-13";
+ break;
+ case 0x0a:
+ charset = "ISO8859-14";
+ break;
+ case 0x0b:
+ charset = "ISO8859-15";
+ break;
+ case 0x11:
+ charset = "UTF16";
+ break;
+ case 0x12:
+ charset = "EUC-KR";
+ break;
+ case 0x13:
+ charset = "GB2312";
+ break;
+ case 0x14:
+ charset = "GBK";
+ break;
+ case 0x15:
+ charset = "UTF8";
+ break;
+ default:
+ used = 0;
+ break;
+ }
+ }
+exit:
+ *consumed = used;
+ return charset;
+}
diff --git a/lib/libucsi/dvb/types.h b/lib/libucsi/dvb/types.h
new file mode 100644
index 0000000..437c7c3
--- /dev/null
+++ b/lib/libucsi/dvb/types.h
@@ -0,0 +1,127 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_TYPES_H
+#define _UCSI_DVB_TYPES_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+#include <time.h>
+
+typedef uint8_t dvbdate_t[5];
+typedef uint8_t dvbduration_t[3];
+typedef uint8_t dvbhhmm_t[2];
+
+/**
+ * Running status values.
+ */
+enum {
+ DVB_RUNNING_STATUS_NOT_RUNNING = 0x01,
+ DVB_RUNNING_STATUS_FEW_SECONDS = 0x02,
+ DVB_RUNNING_STATUS_PAUSING = 0x03,
+ DVB_RUNNING_STATUS_RUNNING = 0x04,
+};
+
+/**
+ * Convert from a 5 byte DVB UTC date to unix time.
+ * Note: this functions expects the DVB date in network byte order.
+ *
+ * @param d Pointer to DVB date.
+ * @return The unix timestamp, or -1 if the dvbdate was set to the 'undefined' value
+ */
+extern time_t dvbdate_to_unixtime(dvbdate_t dvbdate);
+
+/**
+ * Convert from a unix timestemp to a 5 byte DVB UTC date.
+ * Note: this function will always output the DVB date in
+ * network byte order.
+ *
+ * @param unixtime The unix timestamp, or -1 for the 'undefined' value.
+ * @param utc Pointer to 5 byte DVB date.
+ */
+extern void unixtime_to_dvbdate(time_t unixtime, dvbdate_t dvbdate);
+
+/**
+ * Convert from a DVB BCD duration to a number of seconds.
+ *
+ * @param dvbduration Pointer to 3 byte DVB duration.
+ * @return Number of seconds.
+ */
+extern int dvbduration_to_seconds(dvbduration_t dvbduration);
+
+/**
+ * Convert from a number of seconds to a DVB 3 byte BCD duration.
+ *
+ * @param seconds The number of seconds.
+ * @param dvbduration Pointer to 3 byte DVB duration.
+ */
+extern void seconds_to_dvbduration(int seconds, dvbduration_t dvbduration);
+
+/**
+ * Convert from a DVB BCD HHMM to a number of seconds.
+ *
+ * @param dvbduration Pointer to 2 byte DVB HHMM.
+ * @return Number of seconds.
+ */
+extern int dvbhhmm_to_seconds(dvbhhmm_t dvbhhmm);
+
+/**
+ * Convert from a number of seconds to a DVB 2 byte BCD HHMM.
+ *
+ * @param seconds The number of seconds.
+ * @param dvbduration Pointer to 2 byte DVB HHMM.
+ */
+extern void seconds_to_dvbhhmm(int seconds, dvbhhmm_t dvbhhmm);
+
+/**
+ * Convert a __ucsi_packed BCD value into a normal integer.
+ *
+ * @param bcd The value to convert.
+ * @return The value.
+ */
+extern uint32_t bcd_to_integer(uint32_t bcd);
+
+/**
+ * Convert a normal integer into a __ucsi_packed BCD value.
+ *
+ * @param integer The value to convert.
+ * @return The value.
+ */
+extern uint32_t integer_to_bcd(uint32_t integer);
+
+/**
+ * Determine the (iconv compatable) character set of a dvb string.
+ *
+ * @param dvb_text DVB text concerned.
+ * @param dvb_text_length Length of text.
+ * @param consumed Out parameter of number of bytes used to encode the character set.
+ * @return Name of the character set.
+ */
+extern const char *dvb_charset(char *dvb_text, int dvb_text_length, int *consumed);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/vbi_data_descriptor.h b/lib/libucsi/dvb/vbi_data_descriptor.h
new file mode 100644
index 0000000..b1d8703
--- /dev/null
+++ b/lib/libucsi/dvb/vbi_data_descriptor.h
@@ -0,0 +1,186 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_VBI_DATA_DESCRIPTOR
+#define _UCSI_DVB_VBI_DATA_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for the data_service_id field.
+ */
+enum {
+ DVB_VBI_DATA_SERVICE_ID_EBU = 0x01,
+ DVB_VBI_DATA_SERVICE_ID_INVERTED = 0x02,
+ DVB_VBI_DATA_SERVICE_ID_VPS = 0x04,
+ DVB_VBI_DATA_SERVICE_ID_WSS = 0x05,
+ DVB_VBI_DATA_SERVICE_ID_CC = 0x06,
+ DVB_VBI_DATA_SERVICE_ID_MONO_422 = 0x07,
+};
+
+/**
+ * dvb_vbi_data_descriptor structure
+ */
+struct dvb_vbi_data_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_vbi_data_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the dvb_vbi_data_descriptor entries field.
+ */
+struct dvb_vbi_data_entry {
+ uint8_t data_service_id;
+ uint8_t data_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Format of the dvb_vbi_data_entry data field, if data_service_id == 1,2,4,5,6,7.
+ */
+struct dvb_vbi_data_x {
+ EBIT3(uint8_t reserved : 2; ,
+ uint8_t field_parity : 1; ,
+ uint8_t line_offset : 5; );
+} __ucsi_packed;
+
+/**
+ * Process a dvb_vbi_data_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return dvb_vbi_data_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_vbi_data_descriptor*
+ dvb_vbi_data_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* p = (uint8_t*) d + 2;
+ uint32_t pos = 0;
+ uint32_t len = d->len;
+
+ while(pos < len) {
+ struct dvb_vbi_data_entry *e =
+ (struct dvb_vbi_data_entry*) (p+pos);
+
+ pos += sizeof(struct dvb_vbi_data_entry);
+
+ if (pos > len)
+ return NULL;
+
+ pos += e->data_length;
+
+ if (pos > len)
+ return NULL;
+ }
+
+ return (struct dvb_vbi_data_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field in a dvb_vbi_data_descriptor structure.
+ *
+ * @param d Pointer to dvb_vbi_data_descriptor structure.
+ * @param pos Variable holding pointer to the current dvb_vbi_data_entry structure.
+ */
+#define dvb_vbi_data_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_vbi_data_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_vbi_data_descriptor_entries_next(d, pos))
+
+/**
+ * Get a pointer to the data field of a dvb_vbi_data_entry.
+ *
+ * @param d dvb_vbi_data_entry structure.
+ * @return Pointer to the data field.
+ */
+static inline uint8_t *
+ dvb_vbi_data_entry_data(struct dvb_vbi_data_entry *d)
+{
+ return (uint8_t *) d + sizeof(struct dvb_vbi_data_entry);
+}
+
+/**
+ * Get a pointer to the data field of a dvb_vbi_data_x for id 1,2,4,5,6,7.
+ *
+ * @param d dvb_vbi_data_entry structure.
+ * @return Pointer to the data field, or NULL if invalid
+ */
+static inline struct dvb_vbi_data_x*
+ dvb_vbi_data_entry_data_x(struct dvb_vbi_data_entry *d)
+{
+ switch(d->data_service_id) {
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ return (struct dvb_vbi_data_x*) ((uint8_t *) d + sizeof(struct dvb_vbi_data_entry));
+ }
+
+ return NULL;
+}
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_vbi_data_entry*
+ dvb_vbi_data_descriptor_entries_first(struct dvb_vbi_data_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_vbi_data_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_vbi_data_descriptor));
+}
+
+static inline struct dvb_vbi_data_entry*
+ dvb_vbi_data_descriptor_entries_next(struct dvb_vbi_data_descriptor *d,
+ struct dvb_vbi_data_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_vbi_data_entry) +
+ pos->data_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_vbi_data_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/dvb/vbi_teletext_descriptor.h b/lib/libucsi/dvb/vbi_teletext_descriptor.h
new file mode 100644
index 0000000..fd779d7
--- /dev/null
+++ b/lib/libucsi/dvb/vbi_teletext_descriptor.h
@@ -0,0 +1,116 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_DVB_VBI_TELETEXT_DESCRIPTOR
+#define _UCSI_DVB_VBI_TELETEXT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * dvb_vbi_teletext_descriptor structure
+ */
+struct dvb_vbi_teletext_descriptor {
+ struct descriptor d;
+
+ /* struct dvb_vbi_teletext_entry entries[] */
+} __ucsi_packed;
+
+/**
+ * An entry in a dvb_vbi_teletext_descriptor structure.
+ */
+struct dvb_vbi_teletext_entry {
+ iso639lang_t language_code;
+ EBIT2(uint8_t type : 5; ,
+ uint8_t magazine_number: 3; );
+ uint8_t page_number;
+} __ucsi_packed;
+
+/**
+ * Process an dvb_vbi_teletext_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return dvb_vbi_teletext_descriptor pointer, or NULL on error.
+ */
+static inline struct dvb_vbi_teletext_descriptor*
+ dvb_vbi_teletext_descriptor_codec(struct descriptor* d)
+{
+ if (d->len % sizeof(struct dvb_vbi_teletext_entry))
+ return NULL;
+
+ return (struct dvb_vbi_teletext_descriptor*) d;
+}
+
+/**
+ * Iterator for entries field of a dvb_vbi_teletext_descriptor.
+ *
+ * @param d Pointer to dvb_vbi_teletext_descriptor.
+ * @param pos Variable holding a pointer to the current dvb_vbi_teletext_entry.
+ */
+#define dvb_vbi_teletext_descriptor_entries_for_each(d, pos) \
+ for ((pos) = dvb_vbi_teletext_descriptor_entries_first(d); \
+ (pos); \
+ (pos) = dvb_vbi_teletext_descriptor_entries_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct dvb_vbi_teletext_entry*
+ dvb_vbi_teletext_descriptor_entries_first(struct dvb_vbi_teletext_descriptor *d)
+{
+ if (d->d.len == 0)
+ return NULL;
+
+ return (struct dvb_vbi_teletext_entry *)
+ ((uint8_t*) d + sizeof(struct dvb_vbi_teletext_descriptor));
+}
+
+static inline struct dvb_vbi_teletext_entry*
+ dvb_vbi_teletext_descriptor_entries_next(struct dvb_vbi_teletext_descriptor *d,
+ struct dvb_vbi_teletext_entry *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_vbi_teletext_entry);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct dvb_vbi_teletext_entry *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/endianops.h b/lib/libucsi/endianops.h
new file mode 100644
index 0000000..23b418b
--- /dev/null
+++ b/lib/libucsi/endianops.h
@@ -0,0 +1,128 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_COMMON_H
+#define _UCSI_COMMON_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+#include <byteswap.h>
+#include <endian.h>
+
+#define __ucsi_packed __attribute__((packed))
+
+
+
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define EBIT2(x1,x2) x1 x2
+#define EBIT3(x1,x2,x3) x1 x2 x3
+#define EBIT4(x1,x2,x3,x4) x1 x2 x3 x4
+#define EBIT5(x1,x2,x3,x4,x5) x1 x2 x3 x4 x5
+#define EBIT6(x1,x2,x3,x4,x5,x6) x1 x2 x3 x4 x5 x6
+#define EBIT7(x1,x2,x3,x4,x5,x6,x7) x1 x2 x3 x4 x5 x6 x7
+#define EBIT8(x1,x2,x3,x4,x5,x6,x7,x8) x1 x2 x3 x4 x5 x6 x7 x8
+
+static inline void bswap16(uint8_t *buf) {
+ (void) buf;
+}
+
+static inline void bswap32(uint8_t *buf) {
+ (void) buf;
+}
+
+static inline void bswap64(uint8_t *buf) {
+ (void) buf;
+}
+
+static inline void bswap24(uint8_t *buf) {
+ (void) buf;
+}
+
+static inline void bswap40(uint8_t *buf) {
+ (void) buf;
+}
+
+static inline void bswap48(uint8_t *buf) {
+ (void) buf;
+}
+
+#else
+#define EBIT2(x1,x2) x2 x1
+#define EBIT3(x1,x2,x3) x3 x2 x1
+#define EBIT4(x1,x2,x3,x4) x4 x3 x2 x1
+#define EBIT5(x1,x2,x3,x4,x5) x5 x4 x3 x2 x1
+#define EBIT6(x1,x2,x3,x4,x5,x6) x6 x5 x4 x3 x2 x1
+#define EBIT7(x1,x2,x3,x4,x5,x6,x7) x7 x6 x5 x4 x3 x2 x1
+#define EBIT8(x1,x2,x3,x4,x5,x6,x7,x8) x8 x7 x6 x5 x4 x3 x2 x1
+
+static inline void bswap16(uint8_t * buf) {
+ *((uint16_t*)buf) = bswap_16((*(uint16_t*)buf));
+}
+
+static inline void bswap32(uint8_t * buf) {
+ *((uint32_t*)buf) = bswap_32((*(uint32_t*)buf));
+}
+
+static inline void bswap64(uint8_t * buf) {
+ *((uint64_t*)buf) = bswap_64((*(uint64_t*)buf));
+}
+
+static inline void bswap24(uint8_t * buf) {
+ uint8_t tmp0 = buf[0];
+
+ buf[0] = buf[2];
+ buf[2] = tmp0;
+}
+
+static inline void bswap40(uint8_t * buf) {
+ uint8_t tmp0 = buf[0];
+ uint8_t tmp1 = buf[1];
+
+ buf[0] = buf[4];
+ buf[1] = buf[3];
+ buf[3] = tmp1;
+ buf[4] = tmp0;
+}
+
+static inline void bswap48(uint8_t * buf) {
+ uint8_t tmp0 = buf[0];
+ uint8_t tmp1 = buf[1];
+ uint8_t tmp2 = buf[2];
+
+ buf[0] = buf[5];
+ buf[1] = buf[4];
+ buf[2] = buf[3];
+ buf[3] = tmp2;
+ buf[4] = tmp1;
+ buf[5] = tmp0;
+}
+
+#endif // __BYTE_ORDER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/Makefile b/lib/libucsi/mpeg/Makefile
new file mode 100644
index 0000000..ace8808
--- /dev/null
+++ b/lib/libucsi/mpeg/Makefile
@@ -0,0 +1,65 @@
+# Makefile for linuxtv.org dvb-apps/lib/libucsi/mpeg
+
+.PHONY: sub-error-mpeg
+
+sub-error-mpeg:
+ $(error You can't use this makefile directly.)
+
+ifneq ($(lib_name),)
+
+objects += mpeg/cat_section.o \
+ mpeg/metadata_section.o \
+ mpeg/odsmt_section.o \
+ mpeg/pat_section.o \
+ mpeg/pmt_section.o \
+ mpeg/tsdt_section.o
+
+sub-install += mpeg
+
+else
+
+includes = audio_stream_descriptor.h \
+ ca_descriptor.h \
+ cat_section.h \
+ content_labelling_descriptor.h \
+ copyright_descriptor.h \
+ data_stream_alignment_descriptor.h \
+ descriptor.h \
+ external_es_id_descriptor.h \
+ fmc_descriptor.h \
+ fmxbuffer_size_descriptor.h \
+ hierarchy_descriptor.h \
+ ibp_descriptor.h \
+ iod_descriptor.h \
+ iso_639_language_descriptor.h \
+ maximum_bitrate_descriptor.h \
+ metadata_descriptor.h \
+ metadata_pointer_descriptor.h \
+ metadata_section.h \
+ metadata_std_descriptor.h \
+ mpeg4_audio_descriptor.h \
+ mpeg4_video_descriptor.h \
+ multiplex_buffer_descriptor.h \
+ multiplex_buffer_utilization_descriptor.h \
+ muxcode_descriptor.h \
+ odsmt_section.h \
+ pat_section.h \
+ pmt_section.h \
+ private_data_indicator_descriptor.h \
+ registration_descriptor.h \
+ section.h \
+ sl_descriptor.h \
+ smoothing_buffer_descriptor.h \
+ std_descriptor.h \
+ system_clock_descriptor.h \
+ target_background_grid_descriptor.h \
+ tsdt_section.h \
+ types.h \
+ video_stream_descriptor.h \
+ video_window_descriptor.h
+
+include ../../../Make.rules
+
+lib_name = libucsi/mpeg
+
+endif
diff --git a/lib/libucsi/mpeg/audio_stream_descriptor.h b/lib/libucsi/mpeg/audio_stream_descriptor.h
new file mode 100644
index 0000000..7e6ea07
--- /dev/null
+++ b/lib/libucsi/mpeg/audio_stream_descriptor.h
@@ -0,0 +1,65 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_AUDIO_STREAM_DESCRIPTOR
+#define _UCSI_MPEG_AUDIO_STREAM_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_audio_stream_descriptor structure
+ */
+struct mpeg_audio_stream_descriptor {
+ struct descriptor d;
+
+ EBIT5(uint8_t free_format_flag : 1; ,
+ uint8_t id : 1; ,
+ uint8_t layer : 2; ,
+ uint8_t variable_rate_audio_indicator : 1; ,
+ uint8_t reserved : 3; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_audio_stream_descriptor.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_audio_stream_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_audio_stream_descriptor*
+ mpeg_audio_stream_descriptor_codec(struct descriptor *d)
+{
+ if (d->len != (sizeof(struct mpeg_audio_stream_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg_audio_stream_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/ca_descriptor.h b/lib/libucsi/mpeg/ca_descriptor.h
new file mode 100644
index 0000000..88a65dd
--- /dev/null
+++ b/lib/libucsi/mpeg/ca_descriptor.h
@@ -0,0 +1,91 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_CA_DESCRIPTOR
+#define _UCSI_MPEG_CA_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_ca_descriptor structure
+ */
+struct mpeg_ca_descriptor {
+ struct descriptor d;
+
+ uint16_t ca_system_id;
+ EBIT2(uint16_t reserved : 3; ,
+ uint16_t ca_pid : 13; );
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_ca_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return Pointer to an mpeg_ca_descriptor, or NULL on error.
+ */
+static inline struct mpeg_ca_descriptor*
+ mpeg_ca_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct mpeg_ca_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+ bswap16((uint8_t*) d + 4);
+
+ return (struct mpeg_ca_descriptor*) d;
+}
+
+/**
+ * Accessor for pointer to data field of an mpeg_ca_descriptor.
+ *
+ * @param d The mpeg_ca_descriptor structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ mpeg_ca_descriptor_data(struct mpeg_ca_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct mpeg_ca_descriptor);
+}
+
+/**
+ * Determine length of data field of an mpeg_ca_descriptor.
+ *
+ * @param d The mpeg_ca_descriptor structure.
+ * @return Length of the field in bytes.
+ */
+static inline int
+ mpeg_ca_descriptor_data_length(struct mpeg_ca_descriptor *d)
+{
+ return d->d.len - 4;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/cat_section.c b/lib/libucsi/mpeg/cat_section.c
new file mode 100644
index 0000000..8c974b8
--- /dev/null
+++ b/lib/libucsi/mpeg/cat_section.c
@@ -0,0 +1,34 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/cat_section.h>
+
+struct mpeg_cat_section * mpeg_cat_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *)ext;
+ size_t pos = sizeof(struct section_ext);
+
+ if (verify_descriptors(buf + pos,
+ section_ext_length(ext) - sizeof(struct mpeg_cat_section)))
+ return NULL;
+
+ return (struct mpeg_cat_section *)ext;
+}
diff --git a/lib/libucsi/mpeg/cat_section.h b/lib/libucsi/mpeg/cat_section.h
new file mode 100644
index 0000000..7ed34a3
--- /dev/null
+++ b/lib/libucsi/mpeg/cat_section.h
@@ -0,0 +1,94 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_CAT_SECTION_H
+#define _UCSI_MPEG_CAT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * mpeg_cat_section structure.
+ */
+struct mpeg_cat_section {
+ struct section_ext head;
+
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_cat_section.
+ *
+ * @param section The generic section_ext structure.
+ * @return Pointer to an mpeg_cat_section structure, or NULL on error.
+ */
+extern struct mpeg_cat_section *mpeg_cat_section_codec(struct section_ext *section);
+
+/**
+ * Convenience iterator for descriptors field of an mpeg_cat_section.
+ *
+ * @param cat The mpeg_cat_section pointer.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define mpeg_cat_section_descriptors_for_each(cat, pos) \
+ for ((pos) = mpeg_cat_section_descriptors_first(cat); \
+ (pos); \
+ (pos) = mpeg_cat_section_descriptors_next(cat, pos))
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ mpeg_cat_section_descriptors_first(struct mpeg_cat_section *cat)
+{
+ size_t pos = sizeof(struct mpeg_cat_section);
+
+ if (pos >= section_ext_length(&cat->head))
+ return NULL;
+
+ return (struct descriptor*)((uint8_t *) cat + pos);
+}
+
+
+static inline struct descriptor *
+ mpeg_cat_section_descriptors_next(struct mpeg_cat_section *cat,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t *) cat + sizeof(struct mpeg_cat_section),
+ section_ext_length(&cat->head) - sizeof(struct mpeg_cat_section),
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/content_labelling_descriptor.h b/lib/libucsi/mpeg/content_labelling_descriptor.h
new file mode 100644
index 0000000..06738ab
--- /dev/null
+++ b/lib/libucsi/mpeg/content_labelling_descriptor.h
@@ -0,0 +1,356 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_CONTENT_LABELLING_DESCRIPTOR
+#define _UCSI_MPEG_CONTENT_LABELLING_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for content_time_base_indicator.
+ */
+enum {
+ MPEG_CONTENT_TIME_BASE_STC = 0x01,
+ MPEG_CONTENT_TIME_BASE_NPT = 0x02,
+};
+
+/**
+ * mpeg_content_labelling_descriptor structure.
+ */
+struct mpeg_content_labelling_descriptor {
+ struct descriptor d;
+
+ uint16_t metadata_application_format;
+ /* struct mpeg_content_labelling_descriptor_application_format_identifier id */
+ /* struct mpeg_content_labelling_descriptor_flags flags */
+ /* struct mpeg_content_labelling_descriptor_reference_id reference_id */
+ /* struct mpeg_content_labelling_descriptor_time_base time_base */
+ /* struct mpeg_content_labelling_descriptor_content_id content_id */
+ /* struct mpeg_content_labelling_descriptor_time_base_association time_base_assoc */
+ /* uint8_t private_data[] */
+} __ucsi_packed;
+
+/**
+ * id field of a content_labelling_descriptor.
+ */
+struct mpeg_content_labelling_descriptor_application_format_identifier {
+ uint32_t id;
+} __ucsi_packed;
+
+/**
+ * Flags field of a content_labelling_descriptor
+ */
+struct mpeg_content_labelling_descriptor_flags {
+ EBIT3(uint8_t content_reference_id_record_flag : 1; ,
+ uint8_t content_time_base_indicator : 4; ,
+ uint8_t reserved : 3; );
+} __ucsi_packed;
+
+/**
+ * Reference_id field of a content_labelling_descriptor.
+ */
+struct mpeg_content_labelling_descriptor_reference_id {
+ uint8_t content_reference_id_record_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * time_base field of a content_labelling_descriptor.
+ */
+struct mpeg_content_labelling_descriptor_time_base {
+ EBIT2(uint64_t reserved_1 : 7; ,
+ uint64_t content_time_base_value :33; );
+ EBIT2(uint64_t reserved_2 : 7; ,
+ uint64_t metadata_time_base_value :33; );
+} __ucsi_packed;
+
+/**
+ * content_id field of a content_labelling_descriptor.
+ */
+struct mpeg_content_labelling_descriptor_content_id {
+ EBIT2(uint8_t reserved : 1; ,
+ uint8_t contentId : 7; );
+} __ucsi_packed;
+
+/**
+ * time_base_assoc field of a content_labelling_descriptor.
+ */
+struct mpeg_content_labelling_descriptor_time_base_association {
+ uint8_t time_base_association_data_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+
+
+/**
+ * Process an mpeg_content_labelling_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return Pointer to an mpeg_content_labelling_descriptor, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor*
+ mpeg_content_labelling_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 2;
+ uint8_t *buf = (uint8_t*) d;
+ uint32_t len = d->len + 2;
+ struct mpeg_content_labelling_descriptor_flags *flags;
+ int id;
+
+ if (len < sizeof(struct mpeg_content_labelling_descriptor))
+ return NULL;
+
+ bswap16(buf + pos);
+ id = *((uint16_t*) (buf+pos));
+ pos += 2;
+
+ if (id == 0xffff) {
+ if (len < (pos+4))
+ return NULL;
+ bswap32(buf+pos);
+ pos += 4;
+ }
+
+ if (len < (pos + sizeof(struct mpeg_content_labelling_descriptor_flags)))
+ return NULL;
+ flags = (struct mpeg_content_labelling_descriptor_flags*) (buf+pos);
+ pos += sizeof(struct mpeg_content_labelling_descriptor_flags);
+
+ if (flags->content_reference_id_record_flag == 1) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if ((flags->content_time_base_indicator == 1) ||
+ (flags->content_time_base_indicator == 2)) {
+ if (len < (pos + sizeof(struct mpeg_content_labelling_descriptor_time_base)))
+ return NULL;
+ bswap40(buf+pos);
+ bswap40(buf+pos+5);
+ pos += sizeof(struct mpeg_content_labelling_descriptor_time_base);
+ }
+
+ if (flags->content_time_base_indicator == 2) {
+ if (len < (pos + sizeof(struct mpeg_content_labelling_descriptor_content_id)))
+ return NULL;
+ pos += sizeof(struct mpeg_content_labelling_descriptor_content_id);
+ }
+
+ if (flags->content_time_base_indicator > 2) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if (len < pos)
+ return NULL;
+
+ return (struct mpeg_content_labelling_descriptor*) d;
+}
+
+/**
+ * Accessor for pointer to id field of an mpeg_content_labelling_descriptor.
+ *
+ * @param d The mpeg_content_labelling_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor_application_format_identifier*
+ mpeg_content_labelling_descriptor_id(struct mpeg_content_labelling_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d;
+
+ if (d->metadata_application_format != 0xffff)
+ return NULL;
+ return (struct mpeg_content_labelling_descriptor_application_format_identifier*)
+ (buf + sizeof(struct mpeg_content_labelling_descriptor));
+}
+
+/**
+ * Accessor for pointer to flags field of an mpeg_content_labelling_descriptor.
+ *
+ * @param d The mpeg_content_labelling_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor_flags*
+ mpeg_content_labelling_descriptor_flags(struct mpeg_content_labelling_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_content_labelling_descriptor);
+
+ if (d->metadata_application_format != 0xffff)
+ buf += 4;
+
+ return (struct mpeg_content_labelling_descriptor_flags *) buf;
+}
+
+/**
+ * Accessor for reference_id field of an mpeg_content_labelling_descriptor.
+ *
+ * @param flags Pointer to the mpeg_content_labelling_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor_reference_id*
+ mpeg_content_labelling_descriptor_reference_id(struct mpeg_content_labelling_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_content_labelling_descriptor_flags);
+
+ if (flags->content_reference_id_record_flag != 1)
+ return NULL;
+
+ return (struct mpeg_content_labelling_descriptor_reference_id *) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_content_reference_id.
+ *
+ * @param d The mpeg_content_reference_id structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_content_reference_id_data(struct mpeg_content_labelling_descriptor_reference_id *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_content_labelling_descriptor_reference_id);
+}
+
+/**
+ * Accessor for time_base field of an mpeg_content_labelling_descriptor.
+ *
+ * @param flags Pointer to the mpeg_content_labelling_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor_time_base*
+ mpeg_content_labelling_descriptor_time_base(struct mpeg_content_labelling_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_content_labelling_descriptor_flags);
+
+ if ((flags->content_time_base_indicator!=1) && (flags->content_time_base_indicator!=2))
+ return NULL;
+
+ if (flags->content_reference_id_record_flag == 1)
+ buf += 1 + buf[1];
+
+ return (struct mpeg_content_labelling_descriptor_time_base *) buf;
+}
+
+/**
+ * Accessor for content_id field of an mpeg_content_labelling_descriptor.
+ *
+ * @param flags Pointer to the mpeg_content_labelling_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor_content_id*
+ mpeg_content_labelling_descriptor_content_id(struct mpeg_content_labelling_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_content_labelling_descriptor_flags);
+
+ if (flags->content_time_base_indicator!=2)
+ return NULL;
+
+ if (flags->content_reference_id_record_flag == 1)
+ buf += 1 + buf[1];
+ if ((flags->content_time_base_indicator==1) || (flags->content_time_base_indicator==2))
+ buf += sizeof(struct mpeg_content_labelling_descriptor_time_base);
+
+ return (struct mpeg_content_labelling_descriptor_content_id *) buf;
+}
+
+/**
+ * Accessor for time_base_association field of an mpeg_content_labelling_descriptor.
+ *
+ * @param flags Pointer to the mpeg_content_labelling_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_content_labelling_descriptor_time_base_association*
+ mpeg_content_labelling_descriptor_time_base_assoc(struct mpeg_content_labelling_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_content_labelling_descriptor_flags);
+
+ if (flags->content_time_base_indicator<3)
+ return NULL;
+
+ if (flags->content_reference_id_record_flag == 1)
+ buf += 1 + buf[1];
+ if ((flags->content_time_base_indicator==1) || (flags->content_time_base_indicator==2))
+ buf += sizeof(struct mpeg_content_labelling_descriptor_time_base);
+ if (flags->content_time_base_indicator==2)
+ buf += sizeof(struct mpeg_content_labelling_descriptor_content_id);
+
+ return (struct mpeg_content_labelling_descriptor_time_base_association *) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_time_base_association.
+ *
+ * @param d The mpeg_time_base_association structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_time_base_association_data(struct mpeg_content_labelling_descriptor_time_base_association *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_content_labelling_descriptor_time_base_association);
+}
+
+
+/**
+ * Accessor for private_data field of an mpeg_content_labelling_descriptor.
+ *
+ * @param d The mpeg_content_labelling_descriptor structure.
+ * @param flags Pointer to the mpeg_content_labelling_descriptor_flags.
+ * @param length Where the number of bytes in the field should be stored.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_content_labelling_descriptor_data(struct mpeg_content_labelling_descriptor *d,
+ struct mpeg_content_labelling_descriptor_flags *flags,
+ int *length)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_content_labelling_descriptor_flags);
+ uint8_t *end = (uint8_t*) d + d->d.len + 2;
+
+ if (flags->content_reference_id_record_flag == 1)
+ buf += 1 + buf[1];
+ if ((flags->content_time_base_indicator==1) || (flags->content_time_base_indicator==2))
+ buf += sizeof(struct mpeg_content_labelling_descriptor_time_base);
+ if (flags->content_time_base_indicator==2)
+ buf += sizeof(struct mpeg_content_labelling_descriptor_content_id);
+ if (flags->content_time_base_indicator<3)
+ buf += 1 + buf[1];
+
+ *length = end - buf;
+
+ return buf;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/copyright_descriptor.h b/lib/libucsi/mpeg/copyright_descriptor.h
new file mode 100644
index 0000000..5991fe9
--- /dev/null
+++ b/lib/libucsi/mpeg/copyright_descriptor.h
@@ -0,0 +1,89 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_COPYRIGHT_DESCRIPTOR
+#define _UCSI_MPEG_COPYRIGHT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_copyright_descriptor structure.
+ */
+struct mpeg_copyright_descriptor {
+ struct descriptor d;
+
+ uint32_t copyright_identifier;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_copyright_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return mpeg_copyright_descriptor pointer, or NULL on error.
+ */
+static inline struct mpeg_copyright_descriptor*
+ mpeg_copyright_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct mpeg_copyright_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+
+ return (struct mpeg_copyright_descriptor*) d;
+}
+
+/**
+ * Retrieve pointer to data field of an mpeg_copyright_descriptor.
+ *
+ * @param d mpeg_copyright_descriptor pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ mpeg_copyright_descriptor_data(struct mpeg_copyright_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct mpeg_copyright_descriptor);
+}
+
+
+/**
+ * Determine length of the data field of an mpeg_copyright_descriptor.
+ *
+ * @param d mpeg_copyright_descriptor pointer.
+ * @return Length of field in bytes.
+ */
+static inline int
+ mpeg_copyright_descriptor_data_length(struct mpeg_copyright_descriptor *d)
+{
+ return d->d.len - 4;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/data_stream_alignment_descriptor.h b/lib/libucsi/mpeg/data_stream_alignment_descriptor.h
new file mode 100644
index 0000000..887495f
--- /dev/null
+++ b/lib/libucsi/mpeg/data_stream_alignment_descriptor.h
@@ -0,0 +1,73 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_DATA_STREAM_ALIGNMENT_DESCRIPTOR
+#define _UCSI_MPEG_DATA_STREAM_ALIGNMENT_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for alignment_type.
+ */
+enum {
+ MPEG_DATA_STREAM_ALIGNMENT_VIDEO_SLICE_OR_AU = 0x01,
+ MPEG_DATA_STREAM_ALIGNMENT_VIDEO_AU = 0x02,
+ MPEG_DATA_STREAM_ALIGNMENT_VIDEO_GOP_OR_SEQ = 0x03,
+ MPEG_DATA_STREAM_ALIGNMENT_VIDEO_SEQ = 0x04,
+
+ MPEG_DATA_STREAM_ALIGNMENT_AUDIO_SYNC_WORD = 0x01,
+};
+
+/**
+ * mpeg_data_stream_alignment_descriptor structure.
+ */
+struct mpeg_data_stream_alignment_descriptor {
+ struct descriptor d;
+
+ uint8_t alignment_type;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_data_stream_alignment_descriptor.
+ *
+ * @param d Pointer to generic descriptor structure.
+ * @return Pointer to mpeg_data_stream_alignment_descriptor, or NULL on error.
+ */
+static inline struct mpeg_data_stream_alignment_descriptor*
+ mpeg_data_stream_alignment_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_data_stream_alignment_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg_data_stream_alignment_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/descriptor.h b/lib/libucsi/mpeg/descriptor.h
new file mode 100644
index 0000000..c32775f
--- /dev/null
+++ b/lib/libucsi/mpeg/descriptor.h
@@ -0,0 +1,102 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_DESCRIPTOR_H
+#define _UCSI_MPEG_DESCRIPTOR_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/mpeg/mpeg4_audio_descriptor.h>
+#include <libucsi/mpeg/mpeg4_video_descriptor.h>
+#include <libucsi/mpeg/audio_stream_descriptor.h>
+#include <libucsi/mpeg/ca_descriptor.h>
+#include <libucsi/mpeg/content_labelling_descriptor.h>
+#include <libucsi/mpeg/copyright_descriptor.h>
+#include <libucsi/mpeg/data_stream_alignment_descriptor.h>
+#include <libucsi/mpeg/external_es_id_descriptor.h>
+#include <libucsi/mpeg/fmc_descriptor.h>
+#include <libucsi/mpeg/fmxbuffer_size_descriptor.h>
+#include <libucsi/mpeg/hierarchy_descriptor.h>
+#include <libucsi/mpeg/ibp_descriptor.h>
+#include <libucsi/mpeg/iod_descriptor.h>
+#include <libucsi/mpeg/iso_639_language_descriptor.h>
+#include <libucsi/mpeg/maximum_bitrate_descriptor.h>
+#include <libucsi/mpeg/metadata_descriptor.h>
+#include <libucsi/mpeg/metadata_pointer_descriptor.h>
+#include <libucsi/mpeg/metadata_std_descriptor.h>
+#include <libucsi/mpeg/multiplex_buffer_descriptor.h>
+#include <libucsi/mpeg/multiplex_buffer_utilization_descriptor.h>
+#include <libucsi/mpeg/muxcode_descriptor.h>
+#include <libucsi/mpeg/private_data_indicator_descriptor.h>
+#include <libucsi/mpeg/registration_descriptor.h>
+#include <libucsi/mpeg/sl_descriptor.h>
+#include <libucsi/mpeg/smoothing_buffer_descriptor.h>
+#include <libucsi/mpeg/std_descriptor.h>
+#include <libucsi/mpeg/system_clock_descriptor.h>
+#include <libucsi/mpeg/target_background_grid_descriptor.h>
+#include <libucsi/mpeg/video_stream_descriptor.h>
+#include <libucsi/mpeg/video_window_descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Enumeration of MPEG descriptor tags.
+ */
+enum mpeg_descriptor_tag {
+ dtag_mpeg_video_stream = 0x02,
+ dtag_mpeg_audio_stream = 0x03,
+ dtag_mpeg_hierarchy = 0x04,
+ dtag_mpeg_registration = 0x05,
+ dtag_mpeg_data_stream_alignment = 0x06,
+ dtag_mpeg_target_background_grid = 0x07,
+ dtag_mpeg_video_window = 0x08,
+ dtag_mpeg_ca = 0x09,
+ dtag_mpeg_iso_639_language = 0x0a,
+ dtag_mpeg_system_clock = 0x0b,
+ dtag_mpeg_multiplex_buffer_utilization = 0x0c,
+ dtag_mpeg_copyright = 0x0d,
+ dtag_mpeg_maximum_bitrate = 0x0e,
+ dtag_mpeg_private_data_indicator = 0x0f,
+ dtag_mpeg_smoothing_buffer = 0x10,
+ dtag_mpeg_std = 0x11,
+ dtag_mpeg_ibp = 0x12,
+ dtag_mpeg_4_video = 0x1b,
+ dtag_mpeg_4_audio = 0x1c,
+ dtag_mpeg_iod = 0x1d,
+ dtag_mpeg_sl = 0x1e,
+ dtag_mpeg_fmc = 0x1f,
+ dtag_mpeg_external_es_id = 0x20,
+ dtag_mpeg_muxcode = 0x21,
+ dtag_mpeg_fmxbuffer_size = 0x22,
+ dtag_mpeg_multiplex_buffer = 0x23,
+ dtag_mpeg_content_labelling = 0x24,
+ dtag_mpeg_metadata_pointer = 0x25,
+ dtag_mpeg_metadata = 0x26,
+ dtag_mpeg_metadata_std = 0x27,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/external_es_id_descriptor.h b/lib/libucsi/mpeg/external_es_id_descriptor.h
new file mode 100644
index 0000000..3aa3237
--- /dev/null
+++ b/lib/libucsi/mpeg/external_es_id_descriptor.h
@@ -0,0 +1,63 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_EXTERNAL_ES_ID_DESCRIPTOR
+#define _UCSI_MPEG_EXTERNAL_ES_ID_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_external_es_id_descriptor structure.
+ */
+struct mpeg_external_es_id_descriptor {
+ struct descriptor d;
+
+ uint16_t external_es_id;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_external_es_id_descriptor structure.
+ *
+ * @param d Generic descriptor structure.
+ * @return mpeg_external_es_id_descriptor pointer, or NULL on error.
+ */
+static inline struct mpeg_external_es_id_descriptor*
+ mpeg_external_es_id_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_external_es_id_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+
+ return (struct mpeg_external_es_id_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/fmc_descriptor.h b/lib/libucsi/mpeg/fmc_descriptor.h
new file mode 100644
index 0000000..5a5bed2
--- /dev/null
+++ b/lib/libucsi/mpeg/fmc_descriptor.h
@@ -0,0 +1,122 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_FMC_DESCRIPTOR
+#define _UCSI_MPEG_FMC_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_fmc_descriptor structure.
+ */
+struct mpeg_fmc_descriptor {
+ struct descriptor d;
+
+ /* struct mpeg_flex_mux muxes[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the muxes field of an mpeg_fmc_descriptor structure.
+ */
+struct mpeg_flex_mux {
+ uint16_t es_id;
+ uint8_t flex_mux_channel;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_fmc_descriptor structure.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to an mpeg_fmc_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_fmc_descriptor*
+ mpeg_fmc_descriptor_codec(struct descriptor* d)
+{
+ uint8_t* buf = (uint8_t*) d + 2;
+ int pos = 0;
+ int len = d->len;
+
+ if (len % sizeof(struct mpeg_flex_mux))
+ return NULL;
+
+ while(pos < len) {
+ bswap16(buf+pos);
+ pos += sizeof(struct mpeg_flex_mux);
+ }
+
+ return (struct mpeg_fmc_descriptor*) d;
+}
+
+/**
+ * Convenience iterator for the muxes field of an mpeg_fmc_descriptor structure.
+ *
+ * @param d Generic descriptor structure.
+ * @param pos Variable holding a pointer to the the current entry within the muxes field.
+ */
+#define mpeg_fmc_descriptor_muxes_for_each(d, pos) \
+ for ((pos) = mpeg_fmc_descriptor_muxes_first(d); \
+ (pos); \
+ (pos) = mpeg_fmc_descriptor_muxes_next(d, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct mpeg_flex_mux*
+ mpeg_fmc_descriptor_muxes_first(struct mpeg_fmc_descriptor *d)
+{
+ if (d->d.len < sizeof(struct mpeg_flex_mux))
+ return NULL;
+
+ return (struct mpeg_flex_mux *)
+ ((uint8_t*) d + sizeof(struct mpeg_fmc_descriptor));
+}
+
+static inline struct mpeg_flex_mux*
+ mpeg_fmc_descriptor_muxes_next(struct mpeg_fmc_descriptor *d,
+ struct mpeg_flex_mux *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct mpeg_flex_mux);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct mpeg_flex_mux *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/fmxbuffer_size_descriptor.h b/lib/libucsi/mpeg/fmxbuffer_size_descriptor.h
new file mode 100644
index 0000000..74f643c
--- /dev/null
+++ b/lib/libucsi/mpeg/fmxbuffer_size_descriptor.h
@@ -0,0 +1,83 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_FMXBUFFER_SIZE_DESCRIPTOR
+#define _UCSI_MPEG_FMXBUFFER_SIZE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+
+/**
+ * mpeg_fmxbuffer_size_descriptor structure.
+ */
+struct mpeg_fmxbuffer_size_descriptor {
+ struct descriptor d;
+
+ /* uint8_t descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_fmxbuffer_size_descriptor structure.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return Pointer to an mpeg_fmxbuffer_size_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_fmxbuffer_size_descriptor*
+ mpeg_fmxbuffer_size_descriptor_codec(struct descriptor* d)
+{
+ return (struct mpeg_fmxbuffer_size_descriptor*) d;
+}
+
+/**
+ * Retrieve pointer to descriptors field of mpeg_fmxbuffer_size_descriptor structure.
+ *
+ * @param d mpeg_fmxbuffer_size_descriptor structure pointer.
+ * @return Pointer to the descriptors.
+ */
+static inline uint8_t *
+ mpeg_fmxbuffer_size_descriptor_descriptors(struct mpeg_fmxbuffer_size_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct mpeg_fmxbuffer_size_descriptor);
+}
+
+/**
+ * Calculate the length of the descriptors field of an mpeg_fmxbuffer_size_descriptor structure.
+ *
+ * @param d mpeg_fmxbuffer_size_descriptor structure pointer.
+ * @return Length of descriptors in bytes.
+ */
+static inline int
+ mpeg_fmxbuffer_size_descriptor_descriptors_length(struct mpeg_fmxbuffer_size_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/hierarchy_descriptor.h b/lib/libucsi/mpeg/hierarchy_descriptor.h
new file mode 100644
index 0000000..a38539d
--- /dev/null
+++ b/lib/libucsi/mpeg/hierarchy_descriptor.h
@@ -0,0 +1,83 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_HIERARCHY_DESCRIPTOR
+#define _UCSI_MPEG_HIERARCHY_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Hierarchy type values.
+ */
+enum {
+ MPEG_HIERARCHY_TYPE_ISO13818_2_SPATIAL_SCALABILITY = 0x01,
+ MPEG_HIERARCHY_TYPE_ISO13818_2_SNR_SCALABILITY = 0x02,
+ MPEG_HIERARCHY_TYPE_ISO13818_2_TEMPORAL_SCALABILITY = 0x03,
+ MPEG_HIERARCHY_TYPE_ISO13818_2_DATA_PARTITIONING = 0x04,
+ MPEG_HIERARCHY_TYPE_ISO13818_3_EXTENSION_BITSTREAM = 0x05,
+ MPEG_HIERARCHY_TYPE_ISO13818_1_PRIVATE_BITSTREAM = 0x06,
+ MPEG_HIERARCHY_TYPE_ISO13818_2_MULTI_VIEW_PROFILE = 0x07,
+ MPEG_HIERARCHY_TYPE_BASE_LAYER = 0x0f,
+};
+
+
+/**
+ * mpeg_hierarchy_descriptor structure.
+ */
+struct mpeg_hierarchy_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved_1 : 4; ,
+ uint8_t hierarchy_type : 4; );
+ EBIT2(uint8_t reserved_2 : 2; ,
+ uint8_t hierarchy_layer_index : 6; );
+ EBIT2(uint8_t reserved_3 : 2; ,
+ uint8_t hierarchy_embedded_layer_index : 6; );
+ EBIT2(uint8_t reserved_4 : 2; ,
+ uint8_t hierarchy_channel : 6; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_hierarchy_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to mpeg_hierarchy_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_hierarchy_descriptor*
+ mpeg_hierarchy_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_hierarchy_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg_hierarchy_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/ibp_descriptor.h b/lib/libucsi/mpeg/ibp_descriptor.h
new file mode 100644
index 0000000..e82780a
--- /dev/null
+++ b/lib/libucsi/mpeg/ibp_descriptor.h
@@ -0,0 +1,65 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_IBP_DESCRIPTOR
+#define _UCSI_MPEG_IBP_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_ibp_descriptor structure.
+ */
+struct mpeg_ibp_descriptor {
+ struct descriptor d;
+
+ EBIT3(uint16_t closed_gop_flag : 1; ,
+ uint16_t identical_gop_flag : 1; ,
+ uint16_t max_gop_length : 14; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_ibp_descriptor structure.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to the mpeg_ibp_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_ibp_descriptor*
+ mpeg_ibp_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_ibp_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+
+ return (struct mpeg_ibp_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/iod_descriptor.h b/lib/libucsi/mpeg/iod_descriptor.h
new file mode 100644
index 0000000..61de153
--- /dev/null
+++ b/lib/libucsi/mpeg/iod_descriptor.h
@@ -0,0 +1,87 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_IOD_DESCRIPTOR
+#define _UCSI_MPEG_IOD_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_iod_descriptor structure.
+ */
+struct mpeg_iod_descriptor {
+ struct descriptor d;
+
+ uint8_t scope_of_iod_label;
+ uint8_t iod_label;
+ /* uint8_t iod[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_iod_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to an mpeg_iod_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_iod_descriptor*
+ mpeg_iod_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct mpeg_iod_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg_iod_descriptor*) d;
+}
+
+/**
+ * Retrieve pointer to iod field of an mpeg_iod_descriptor structure.
+ *
+ * @param d Pointer to mpeg_iod_descriptor structure.
+ * @return Pointer to the iod field.
+ */
+static inline uint8_t *
+ mpeg_iod_descriptor_iod(struct mpeg_iod_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct mpeg_iod_descriptor);
+}
+
+/**
+ * Calculate the length of the iod field of an mpeg_iod_descriptor structure.
+ *
+ * @param d Pointer to mpeg_iod_descriptor structure.
+ * @return The number of bytes.
+ */
+static inline int
+ mpeg_iod_descriptor_iod_length(struct mpeg_iod_descriptor *d)
+{
+ return d->d.len - 2;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/iso_639_language_descriptor.h b/lib/libucsi/mpeg/iso_639_language_descriptor.h
new file mode 100644
index 0000000..5b5aac0
--- /dev/null
+++ b/lib/libucsi/mpeg/iso_639_language_descriptor.h
@@ -0,0 +1,124 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_ISO_639_LANGUAGE_DESCRIPTOR
+#define _UCSI_MPEG_ISO_639_LANGUAGE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+#include <libucsi/types.h>
+
+/**
+ * Possible values for audio_type.
+ */
+enum {
+ MPEG_AUDIO_TYPE_CLEAN_EFFECTS = 0x01,
+ MPEG_AUDIO_TYPE_HEARING_IMPAIRED = 0x02,
+ MPEG_AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY = 0x03,
+};
+
+/**
+ * mpeg_iso_639_language_descriptor structure.
+ */
+struct mpeg_iso_639_language_descriptor {
+ struct descriptor d;
+
+ /* struct mpeg_iso_639_language_code languages[] */
+} __ucsi_packed;
+
+/**
+ * An entry in the mpeg_iso_639_language_descriptor languages field.
+ */
+struct mpeg_iso_639_language_code {
+ iso639lang_t language_code;
+ uint8_t audio_type;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_iso_639_language_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to an mpeg_iso_639_language_descriptor structure, or NULL
+ * on error.
+ */
+static inline struct mpeg_iso_639_language_descriptor*
+ mpeg_iso_639_language_descriptor_codec(struct descriptor* d)
+{
+ if (d->len % sizeof(struct mpeg_iso_639_language_code))
+ return NULL;
+
+ return (struct mpeg_iso_639_language_descriptor*) d;
+}
+
+/**
+ * Convenience iterator for the languages field of an mpeg_iso_639_language_descriptor
+ *
+ * @param d Pointer to the mpeg_iso_639_language_descriptor structure.
+ * @param pos Variable holding a pointer to the current entry.
+ */
+#define mpeg_iso_639_language_descriptor_languages_for_each(_d, _pos) \
+ for ((_pos) = mpeg_iso_639_language_descriptor_languages_first(_d); \
+ (_pos); \
+ (_pos) = mpeg_iso_639_language_descriptor_languages_next(_d, _pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct mpeg_iso_639_language_code*
+ mpeg_iso_639_language_descriptor_languages_first(struct mpeg_iso_639_language_descriptor *d)
+{
+ if (d->d.len < sizeof(struct mpeg_iso_639_language_code))
+ return NULL;
+
+ return (struct mpeg_iso_639_language_code *)
+ ((uint8_t*) d + sizeof(struct mpeg_iso_639_language_descriptor));
+}
+
+static inline struct mpeg_iso_639_language_code*
+ mpeg_iso_639_language_descriptor_languages_next(struct mpeg_iso_639_language_descriptor *d,
+ struct mpeg_iso_639_language_code *pos)
+{
+ uint8_t *end = (uint8_t*) d + 2 + d->d.len;
+ uint8_t *next = (uint8_t *) pos + sizeof(struct mpeg_iso_639_language_code);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct mpeg_iso_639_language_code *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/maximum_bitrate_descriptor.h b/lib/libucsi/mpeg/maximum_bitrate_descriptor.h
new file mode 100644
index 0000000..e0bcddb
--- /dev/null
+++ b/lib/libucsi/mpeg/maximum_bitrate_descriptor.h
@@ -0,0 +1,64 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_MAXIMUM_BITRATE_DESCRIPTOR
+#define _UCSI_MPEG_MAXIMUM_BITRATE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_maximum_bitrate_descriptor structure.
+ */
+struct mpeg_maximum_bitrate_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint32_t reserved : 2; ,
+ uint32_t maximum_bitrate : 22; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_maximum_bitrate_descriptor.
+ *
+ * @param d Pointer to generic descriptor structure.
+ * @return Pointer to mpeg_maximum_bitrate_descriptor, or NULL on error.
+ */
+static inline struct mpeg_maximum_bitrate_descriptor*
+ mpeg_maximum_bitrate_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_maximum_bitrate_descriptor) - 2))
+ return NULL;
+
+ bswap24((uint8_t*) d + 2);
+
+ return (struct mpeg_maximum_bitrate_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/metadata_descriptor.h b/lib/libucsi/mpeg/metadata_descriptor.h
new file mode 100644
index 0000000..5b91e05
--- /dev/null
+++ b/lib/libucsi/mpeg/metadata_descriptor.h
@@ -0,0 +1,472 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_METADATA_DESCRIPTOR
+#define _UCSI_MPEG_METADATA_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Values for the decoder_config_flags field.
+ */
+enum {
+ MPEG_DECODER_CONFIG_NONE = 0x00,
+ MPEG_DECODER_CONFIG_IN_DECODER_CONFIG = 0x01,
+ MPEG_DECODER_CONFIG_SAME_METADATA_SERVICE = 0x02,
+ MPEG_DECODER_CONFIG_DSMCC = 0x03,
+ MPEG_DECODER_CONFIG_SAME_PROGRAM = 0x04,
+};
+
+/**
+ * mpeg_metadata_descriptor structure.
+ */
+struct mpeg_metadata_descriptor {
+ struct descriptor d;
+
+ uint16_t metadata_application_format;
+ /* struct mpeg_metadata_descriptor_application_format_identifier appid */
+ /* uint8_t metadata_format */
+ /* struct mpeg_metadata_descriptor_format_identifier formid */
+ /* struct mpeg_metadata_descriptor_flags flags */
+ /* struct mpeg_metadata_descriptor_service_identifier service_identifier */
+ /* struct mpeg_metadata_descriptor_decoder_config decoder_config */
+ /* struct mpeg_metadata_descriptor_decoder_config_id_record decoder_config_id_record */
+ /* struct mpeg_metadata_descriptor_decoder_config_service_id decoder_config_service_id */
+ /* struct mpeg_metadata_descriptor_decoder_config_reserved decoder_config_reserved */
+ /* uint8_t private_data[] */
+} __ucsi_packed;
+
+/**
+ * appid field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_application_format_identifier {
+ uint32_t id;
+} __ucsi_packed;
+
+/**
+ * formid field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_format_identifier {
+ uint32_t id;
+} __ucsi_packed;
+
+/**
+ * Flags field of a metadata_descriptor
+ */
+struct mpeg_metadata_descriptor_flags {
+ uint8_t metadata_service_id;
+ EBIT3(uint8_t decoder_config_flags : 3; ,
+ uint8_t dsm_cc_flag : 1; ,
+ uint8_t reserved : 4; );
+} __ucsi_packed;
+
+/**
+ * service_identifier field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_service_identifier {
+ uint8_t service_identification_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * decoder_config field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_decoder_config {
+ uint8_t decoder_config_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * decoder_config_id_record field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_decoder_config_id_record {
+ uint8_t decoder_config_id_record_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * decoder_config_service_id field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_decoder_config_service_id {
+ uint8_t decoder_config_metadata_service_id;
+} __ucsi_packed;
+
+/**
+ * decoder_config_reserved field of a metadata_descriptor.
+ */
+struct mpeg_metadata_descriptor_decoder_config_reserved {
+ uint8_t reserved_data_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+
+
+
+/**
+ * Process an mpeg_metadata_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return Pointer to an mpeg_metadata_descriptor, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor*
+ mpeg_metadata_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 2;
+ uint8_t *buf = (uint8_t*) d;
+ uint32_t len = d->len + 2;
+ struct mpeg_metadata_descriptor_flags *flags;
+ int id;
+
+ if (len < sizeof(struct mpeg_metadata_descriptor))
+ return NULL;
+
+ bswap16(buf + pos);
+ id = *((uint16_t*) (buf+pos));
+ pos += 2;
+
+ if (id == 0xffff) {
+ if (len < (pos+4))
+ return NULL;
+ bswap32(buf+pos);
+ pos += 4;
+ }
+
+ if (len < (pos+1))
+ return NULL;
+
+ id = buf[pos];
+ pos++;
+ if (id == 0xff) {
+ if (len < (pos+4))
+ return NULL;
+ bswap32(buf+pos);
+ pos += 4;
+ }
+
+ if (len < (pos + sizeof(struct mpeg_metadata_descriptor_flags)))
+ return NULL;
+ flags = (struct mpeg_metadata_descriptor_flags*) (buf+pos);
+ pos += sizeof(struct mpeg_metadata_descriptor_flags);
+
+ if (flags->dsm_cc_flag == 1) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if (flags->decoder_config_flags == 1) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if (flags->decoder_config_flags == 3) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if (flags->decoder_config_flags == 4) {
+ if (len < (pos+1))
+ return NULL;
+ pos++;
+ }
+
+ if ((flags->decoder_config_flags == 5) ||
+ (flags->decoder_config_flags == 6)) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if (len < pos)
+ return NULL;
+
+ return (struct mpeg_metadata_descriptor*) d;
+}
+
+/**
+ * Accessor for pointer to appid field of an mpeg_metadata_descriptor.
+ *
+ * @param d The mpeg_metadata_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_application_format_identifier*
+ mpeg_metadata_descriptor_appid(struct mpeg_metadata_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor);
+
+ if (d->metadata_application_format != 0xffff)
+ return NULL;
+ return (struct mpeg_metadata_descriptor_application_format_identifier*) buf;
+}
+
+/**
+ * Accessor for metadata_format field of an mpeg_metadata_descriptor.
+ *
+ * @param d The mpeg_metadata_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline uint8_t
+ mpeg_metadata_descriptor_metadata_format(struct mpeg_metadata_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor);
+
+ if (d->metadata_application_format == 0xffff)
+ buf+=4;
+ return *buf;
+}
+
+/**
+ * Accessor for pointer to formid field of an mpeg_metadata_descriptor.
+ *
+ * @param d The mpeg_metadata_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_format_identifier*
+ mpeg_metadata_descriptor_formid(struct mpeg_metadata_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor);
+
+ if (d->metadata_application_format == 0xffff)
+ buf+=4;
+ if (*buf != 0xff)
+ return NULL;
+
+ return (struct mpeg_metadata_descriptor_format_identifier*) (buf+1);
+}
+
+/**
+ * Accessor for flags field of an mpeg_metadata_descriptor.
+ *
+ * @param d The mpeg_metadata_descriptor structure.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_flags*
+ mpeg_metadata_descriptor_flags(struct mpeg_metadata_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor);
+
+ if (d->metadata_application_format == 0xffff)
+ buf+=4;
+ if (*buf == 0xff)
+ buf+=4;
+
+ return (struct mpeg_metadata_descriptor_flags*) buf;
+}
+
+
+/**
+ * Accessor for service_identifier field of an mpeg_metadata_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_service_identifier*
+ mpeg_metadata_descriptor_sevice_identifier(struct mpeg_metadata_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_descriptor_flags);
+
+ if (flags->dsm_cc_flag!=1)
+ return NULL;
+
+ return (struct mpeg_metadata_descriptor_service_identifier *) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_metadata_descriptor_service_identifier.
+ *
+ * @param d The mpeg_metadata_descriptor_service_identifier structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_descriptor_service_identifier_data(struct mpeg_metadata_descriptor_service_identifier *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor_service_identifier);
+}
+
+/**
+ * Accessor for decoder_config field of an mpeg_metadata_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_decoder_config*
+ mpeg_metadata_descriptor_decoder_config(struct mpeg_metadata_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_descriptor_flags);
+
+ if (flags->decoder_config_flags != 1)
+ return NULL;
+
+ if (flags->dsm_cc_flag==1)
+ buf += 1 + buf[1];
+
+ return (struct mpeg_metadata_descriptor_decoder_config*) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_metadata_descriptor_service_identifier.
+ *
+ * @param d The mpeg_metadata_descriptor_service_identifier structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_descriptor_decoder_config_data(struct mpeg_metadata_descriptor_decoder_config *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor_decoder_config);
+}
+
+/**
+ * Accessor for decoder_config_id_record field of an mpeg_metadata_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_decoder_config_id_record*
+ mpeg_metadata_descriptor_decoder_config_id_record(struct mpeg_metadata_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_descriptor_flags);
+
+ if (flags->decoder_config_flags != 3)
+ return NULL;
+
+ if (flags->dsm_cc_flag==1)
+ buf += 1 + buf[1];
+
+ return (struct mpeg_metadata_descriptor_decoder_config_id_record *) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_metadata_descriptor_decoder_config_id_record.
+ *
+ * @param d The mpeg_metadata_descriptor_decoder_config_id_record structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_descriptor_decoder_config_id_record_data(struct mpeg_metadata_descriptor_decoder_config_id_record *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor_decoder_config_id_record);
+}
+
+/**
+ * Accessor for decoder_config_service_id field of an mpeg_metadata_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_decoder_config_service_id*
+ mpeg_metadata_descriptor_decoder_config_service_id(struct mpeg_metadata_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_descriptor_flags);
+
+ if (flags->decoder_config_flags != 4)
+ return NULL;
+
+ if (flags->dsm_cc_flag==1)
+ buf += 1 + buf[1];
+
+ return (struct mpeg_metadata_descriptor_decoder_config_service_id *) buf;
+}
+
+/**
+ * Accessor for decoder_config_reserved field of an mpeg_metadata_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_descriptor_decoder_config_reserved*
+ mpeg_metadata_descriptor_decoder_config_reserved(struct mpeg_metadata_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_descriptor_flags);
+
+ if ((flags->decoder_config_flags != 5) && (flags->decoder_config_flags != 6))
+ return NULL;
+
+ if (flags->dsm_cc_flag==1)
+ buf += 1 + buf[1];
+
+ return (struct mpeg_metadata_descriptor_decoder_config_reserved *) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_metadata_descriptor_decoder_config_reserved.
+ *
+ * @param d The mpeg_metadata_descriptor_decoder_config_reserved structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_descriptor_decoder_config_reserved_data(struct mpeg_metadata_descriptor_decoder_config_reserved *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_metadata_descriptor_decoder_config_reserved);
+}
+
+/**
+ * Accessor for private_data field of an mpeg_metadata_descriptor.
+ *
+ * @param d The mpeg_metadata_descriptor structure.
+ * @param flags Pointer to the mpeg_metadata_descriptor_flags.
+ * @param length Where the number of bytes in the field should be stored.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_descriptor_private_data(struct mpeg_metadata_descriptor *d,
+ struct mpeg_metadata_descriptor_flags *flags,
+ int *length)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_descriptor_flags);
+ uint8_t *end = (uint8_t*) d + d->d.len + 2;
+
+
+ if (flags->dsm_cc_flag==1)
+ buf += 1 + buf[1];
+ if (flags->decoder_config_flags==1)
+ buf += 1 + buf[1];
+ if (flags->decoder_config_flags==3)
+ buf += 1 + buf[1];
+ if (flags->decoder_config_flags==4)
+ buf++;
+ if ((flags->decoder_config_flags==5)||(flags->decoder_config_flags==6))
+ buf += 1 + buf[1];
+
+ *length = end - buf;
+ return buf;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/metadata_pointer_descriptor.h b/lib/libucsi/mpeg/metadata_pointer_descriptor.h
new file mode 100644
index 0000000..e4d7503
--- /dev/null
+++ b/lib/libucsi/mpeg/metadata_pointer_descriptor.h
@@ -0,0 +1,360 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_METADATA_POINTER_DESCRIPTOR
+#define _UCSI_MPEG_METADATA_POINTER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * Possible values for the mpeg_carriage_flags field.
+ */
+enum {
+ MPEG_CARRIAGE_SAME_TS = 0x00,
+ MPEG_CARRIAGE_DIFFERENT_TS = 0x01,
+ MPEG_CARRIAGE_PS = 0x02,
+ MPEG_CARRIAGE_OTHER = 0x03,
+};
+
+/**
+ * mpeg_metadata_pointer_descriptor structure.
+ */
+struct mpeg_metadata_pointer_descriptor {
+ struct descriptor d;
+
+ uint16_t metadata_application_format;
+ /* struct mpeg_metadata_pointer_descriptor_application_format_identifier appid */
+ /* uint8_t metadata_format */
+ /* struct mpeg_metadata_pointer_descriptor_format_identifier formid */
+ /* struct mpeg_metadata_pointer_descriptor_flags flags */
+ /* struct mpeg_metadata_pointer_descriptor_locator locator */
+ /* struct mpeg_metadata_pointer_descriptor_program_number program_number */
+ /* struct mpeg_metadata_pointer_descriptor_carriage carriage */
+ /* uint8_t private_data[] */
+} __ucsi_packed;
+
+/**
+ * appid field of a metadata_pointer_descriptor.
+ */
+struct mpeg_metadata_pointer_descriptor_application_format_identifier {
+ uint32_t id;
+} __ucsi_packed;
+
+/**
+ * formid field of a metadata_pointer_descriptor.
+ */
+struct mpeg_metadata_pointer_descriptor_format_identifier {
+ uint32_t id;
+} __ucsi_packed;
+
+/**
+ * Flags field of a metadata_pointer_descriptor
+ */
+struct mpeg_metadata_pointer_descriptor_flags {
+ uint8_t metadata_service_id;
+ EBIT3(uint8_t metadata_locator_record_flag : 1; ,
+ uint8_t mpeg_carriage_flags : 2; ,
+ uint8_t reserved : 5; );
+} __ucsi_packed;
+
+/**
+ * Reference_id field of a metadata_pointer_descriptor.
+ */
+struct mpeg_metadata_pointer_descriptor_locator {
+ uint8_t metadata_locator_record_length;
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * program_number field of a metadata_pointer_descriptor.
+ */
+struct mpeg_metadata_pointer_descriptor_program_number {
+ uint16_t number;
+} __ucsi_packed;
+
+/**
+ * carriage field of a metadata_pointer_descriptor.
+ */
+struct mpeg_metadata_pointer_descriptor_carriage {
+ uint16_t transport_stream_location;
+ uint16_t transport_stream_id;
+} __ucsi_packed;
+
+
+
+
+/**
+ * Process an mpeg_metadata_pointer_descriptor.
+ *
+ * @param d Generic descriptor.
+ * @return Pointer to an mpeg_metadata_pointer_descriptor, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor*
+ mpeg_metadata_pointer_descriptor_codec(struct descriptor* d)
+{
+ uint32_t pos = 2;
+ uint8_t *buf = (uint8_t*) d;
+ uint32_t len = d->len + 2;
+ struct mpeg_metadata_pointer_descriptor_flags *flags;
+ int id;
+
+ if (len < sizeof(struct mpeg_metadata_pointer_descriptor))
+ return NULL;
+
+ bswap16(buf + pos);
+ id = *((uint16_t*) (buf+pos));
+ pos += 2;
+
+ if (id == 0xffff) {
+ if (len < (pos+4))
+ return NULL;
+ bswap32(buf+pos);
+ pos += 4;
+ }
+
+ if (len < (pos+1))
+ return NULL;
+
+ id = buf[pos];
+ pos++;
+ if (id == 0xff) {
+ if (len < (pos+4))
+ return NULL;
+ bswap32(buf+pos);
+ pos += 4;
+ }
+
+ if (len < (pos + sizeof(struct mpeg_metadata_pointer_descriptor_flags)))
+ return NULL;
+ flags = (struct mpeg_metadata_pointer_descriptor_flags*) (buf+pos);
+ pos += sizeof(struct mpeg_metadata_pointer_descriptor_flags);
+
+ if (flags->metadata_locator_record_flag == 1) {
+ if (len < (pos+1))
+ return NULL;
+ if (len < (pos+1+buf[pos]))
+ return NULL;
+ pos += 1 + buf[pos];
+ }
+
+ if (flags->mpeg_carriage_flags < 3) {
+ if (len < (pos + 2))
+ return NULL;
+ bswap16(buf+pos);
+ pos += 2;
+ }
+
+ if (flags->mpeg_carriage_flags == 1) {
+ if (len < (pos + 4))
+ return NULL;
+ bswap16(buf+pos);
+ bswap16(buf+pos+2);
+ pos += 4;
+ }
+
+ if (len < pos)
+ return NULL;
+
+ return (struct mpeg_metadata_pointer_descriptor*) d;
+}
+
+/**
+ * Accessor for pointer to appid field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param d The mpeg_metadata_pointer_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor_application_format_identifier*
+ mpeg_metadata_pointer_descriptor_appid(struct mpeg_metadata_pointer_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_pointer_descriptor);
+
+ if (d->metadata_application_format != 0xffff)
+ return NULL;
+ return (struct mpeg_metadata_pointer_descriptor_application_format_identifier*) buf;
+}
+
+/**
+ * Accessor for metadata_format field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param d The mpeg_metadata_pointer_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline uint8_t
+ mpeg_metadata_pointer_descriptor_metadata_format(struct mpeg_metadata_pointer_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_pointer_descriptor);
+
+ if (d->metadata_application_format == 0xffff)
+ buf+=4;
+ return *buf;
+}
+
+/**
+ * Accessor for pointer to formid field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param d The mpeg_metadata_pointer_descriptor structure.
+ * @return The pointer, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor_format_identifier*
+ mpeg_metadata_pointer_descriptor_formid(struct mpeg_metadata_pointer_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_pointer_descriptor);
+
+ if (d->metadata_application_format == 0xffff)
+ buf+=4;
+ if (*buf != 0xff)
+ return NULL;
+
+ return (struct mpeg_metadata_pointer_descriptor_format_identifier*) (buf+1);
+}
+
+/**
+ * Accessor for flags field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param d The mpeg_metadata_pointer_descriptor structure.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor_flags*
+ mpeg_metadata_pointer_descriptor_flags(struct mpeg_metadata_pointer_descriptor *d)
+{
+ uint8_t *buf = (uint8_t*) d + sizeof(struct mpeg_metadata_pointer_descriptor);
+
+ if (d->metadata_application_format == 0xffff)
+ buf+=4;
+ if (*buf == 0xff)
+ buf+=4;
+
+ return (struct mpeg_metadata_pointer_descriptor_flags*) buf;
+}
+
+
+/**
+ * Accessor for locator field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_pointer_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor_locator*
+ mpeg_metadata_pointer_descriptor_locator(struct mpeg_metadata_pointer_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_pointer_descriptor_flags);
+
+ if (flags->metadata_locator_record_flag!=1)
+ return NULL;
+
+ return (struct mpeg_metadata_pointer_descriptor_locator *) buf;
+}
+
+/**
+ * Accessor for data field of an mpeg_metadata_pointer_descriptor_locator.
+ *
+ * @param d The mpeg_metadata_pointer_descriptor_locator structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_pointer_descriptor_locator_data(struct mpeg_metadata_pointer_descriptor_locator *d)
+{
+ return (uint8_t*) d + sizeof(struct mpeg_metadata_pointer_descriptor_locator);
+}
+
+
+/**
+ * Accessor for program_number field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_pointer_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor_program_number*
+ mpeg_metadata_pointer_descriptor_program_number(struct mpeg_metadata_pointer_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_pointer_descriptor_flags);
+
+ if (flags->mpeg_carriage_flags < 3)
+ return NULL;
+
+ if (flags->metadata_locator_record_flag==1)
+ buf += 1 + buf[1];
+
+ return (struct mpeg_metadata_pointer_descriptor_program_number*) buf;
+}
+
+/**
+ * Accessor for carriage field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param flags Pointer to the mpeg_metadata_pointer_descriptor_flags.
+ * @return Pointer to the field, or NULL on error.
+ */
+static inline struct mpeg_metadata_pointer_descriptor_carriage*
+ mpeg_metadata_pointer_descriptor_carriage(struct mpeg_metadata_pointer_descriptor_flags *flags)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_pointer_descriptor_flags);
+
+ if (flags->mpeg_carriage_flags != 1)
+ return NULL;
+
+ if (flags->metadata_locator_record_flag==1)
+ buf += 1 + buf[1];
+ if (flags->mpeg_carriage_flags < 3)
+ buf += sizeof(struct mpeg_metadata_pointer_descriptor_program_number);
+
+ return (struct mpeg_metadata_pointer_descriptor_carriage *) buf;
+}
+
+/**
+ * Accessor for private_data field of an mpeg_metadata_pointer_descriptor.
+ *
+ * @param d The mpeg_metadata_pointer_descriptor structure.
+ * @param flags Pointer to the mpeg_metadata_pointer_descriptor_flags.
+ * @param length Where the number of bytes in the field should be stored.
+ * @return Pointer to the field.
+ */
+static inline uint8_t*
+ mpeg_metadata_pointer_descriptor_private_data(struct mpeg_metadata_pointer_descriptor *d,
+ struct mpeg_metadata_pointer_descriptor_flags *flags,
+ int *length)
+{
+ uint8_t *buf = (uint8_t*) flags + sizeof(struct mpeg_metadata_pointer_descriptor_flags);
+ uint8_t *end = (uint8_t*) d + d->d.len + 2;
+
+
+ if (flags->metadata_locator_record_flag==1)
+ buf += 1 + buf[1];
+ if (flags->mpeg_carriage_flags < 3)
+ buf += sizeof(struct mpeg_metadata_pointer_descriptor_program_number);
+ if (flags->mpeg_carriage_flags != 1)
+ buf += sizeof(struct mpeg_metadata_pointer_descriptor_carriage);
+
+ *length = end - buf;
+ return buf;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/metadata_section.c b/lib/libucsi/mpeg/metadata_section.c
new file mode 100644
index 0000000..c1ce019
--- /dev/null
+++ b/lib/libucsi/mpeg/metadata_section.c
@@ -0,0 +1,27 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/metadata_section.h>
+
+struct mpeg_metadata_section * mpeg_metadata_section_codec(struct section_ext * ext)
+{
+ return (struct mpeg_metadata_section *)ext;
+}
diff --git a/lib/libucsi/mpeg/metadata_section.h b/lib/libucsi/mpeg/metadata_section.h
new file mode 100644
index 0000000..62c4e03
--- /dev/null
+++ b/lib/libucsi/mpeg/metadata_section.h
@@ -0,0 +1,122 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_METADATA_SECTION_H
+#define _UCSI_MPEG_METADATA_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * mpeg_metadata_section structure.
+ */
+struct mpeg_metadata_section {
+ struct section_ext head;
+
+ /* uint8_t data[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_metadata_section structure.
+ *
+ * @param section Pointer to the section_ext structure.
+ * @return Pointer to the mpeg_metadata_section structure, or NULL on error.
+ */
+extern struct mpeg_metadata_section *mpeg_metadata_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the random_access_indicator field of a metadata section.
+ *
+ * @param metadata metadata section pointer.
+ * @return The random_access_indicator.
+ */
+static inline uint8_t mpeg_metadata_section_random_access_indicator(struct mpeg_metadata_section *metadata)
+{
+ return metadata->head.reserved >> 1;
+}
+
+/**
+ * Accessor for the decoder_config_flag field of a metadata section.
+ *
+ * @param metadata metadata section pointer.
+ * @return The decoder_config_flag.
+ */
+static inline uint8_t mpeg_metadata_section_decoder_config_flag(struct mpeg_metadata_section *metadata)
+{
+ return metadata->head.reserved & 1;
+}
+
+/**
+ * Accessor for the fragment_indicator field of a metadata section.
+ *
+ * @param metadata metadata section pointer.
+ * @return The fragment_indicator.
+ */
+static inline uint8_t mpeg_metadata_section_fragment_indicator(struct mpeg_metadata_section *metadata)
+{
+ return metadata->head.reserved1;
+}
+
+/**
+ * Accessor for the service_id field of a metadata section.
+ *
+ * @param metadata metadata section pointer.
+ * @return The service_id.
+ */
+static inline uint16_t mpeg_metadata_section_service_id(struct mpeg_metadata_section *metadata)
+{
+ return metadata->head.table_id_ext >> 8;
+}
+
+/**
+ * Retrieve pointer to data field of an mpeg_metadata_section.
+ *
+ * @param s mpeg_metadata_section pointer.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ mpeg_metadata_section_data(struct mpeg_metadata_section *s)
+{
+ return (uint8_t *) s + sizeof(struct mpeg_metadata_section);
+}
+
+
+/**
+ * Determine length of the data field of an mpeg_copyright_descriptor.
+ *
+ * @param s mpeg_metadata_section_data pointer.
+ * @return Length of field in bytes.
+ */
+static inline int
+ mpeg_metadata_section_data_length(struct mpeg_metadata_section *s)
+{
+ return section_ext_length(&s->head) - sizeof(struct mpeg_metadata_section);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/metadata_std_descriptor.h b/lib/libucsi/mpeg/metadata_std_descriptor.h
new file mode 100644
index 0000000..fc83e6e
--- /dev/null
+++ b/lib/libucsi/mpeg/metadata_std_descriptor.h
@@ -0,0 +1,72 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_METADATA_STD_DESCRIPTOR
+#define _UCSI_MPEG_METADATA_STD_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_metadata_std_descriptor structure.
+ */
+struct mpeg_metadata_std_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint32_t reserved_1 : 2; ,
+ uint32_t metadata_input_leak_rate :22; );
+ EBIT2(uint32_t reserved_2 : 2; ,
+ uint32_t metadata_buffer_size :22; );
+ EBIT2(uint32_t reserved_3 : 2; ,
+ uint32_t metadata_output_leak_rate :22; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_metadata_std_descriptor.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_metadata_std_descriptor, or NULL on error.
+ */
+static inline struct mpeg_metadata_std_descriptor*
+ mpeg_metadata_std_descriptor_codec(struct descriptor* d)
+{
+ uint8_t *buf = (uint8_t*) d;
+
+ if (d->len != (sizeof(struct mpeg_metadata_std_descriptor) - 2))
+ return NULL;
+
+ bswap24(buf + 2);
+ bswap24(buf + 5);
+ bswap24(buf + 8);
+
+ return (struct mpeg_metadata_std_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/mpeg4_audio_descriptor.h b/lib/libucsi/mpeg/mpeg4_audio_descriptor.h
new file mode 100644
index 0000000..f876759
--- /dev/null
+++ b/lib/libucsi/mpeg/mpeg4_audio_descriptor.h
@@ -0,0 +1,61 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG4_AUDIO_DESCRIPTOR
+#define _UCSI_MPEG4_AUDIO_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg4_audio_descriptor structure.
+ */
+struct mpeg4_audio_descriptor {
+ struct descriptor d;
+
+ uint8_t mpeg4_audio_profile_and_level;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg4_audio_descriptor.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to an mpeg4_audio_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg4_audio_descriptor*
+ mpeg4_audio_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg4_audio_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg4_audio_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/mpeg4_video_descriptor.h b/lib/libucsi/mpeg/mpeg4_video_descriptor.h
new file mode 100644
index 0000000..b956b91
--- /dev/null
+++ b/lib/libucsi/mpeg/mpeg4_video_descriptor.h
@@ -0,0 +1,61 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG4_VIDEO_DESCRIPTOR
+#define _UCSI_MPEG4_VIDEO_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg4_video_descriptor structure.
+ */
+struct mpeg4_video_descriptor {
+ struct descriptor d;
+
+ uint8_t mpeg4_visual_profile_and_level;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg4_video_descriptor structure.
+ *
+ * @param d Pointer to generic descriptor structure.
+ * @return Pointer to mpeg4_video_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg4_video_descriptor*
+ mpeg4_video_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg4_video_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg4_video_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/multiplex_buffer_descriptor.h b/lib/libucsi/mpeg/multiplex_buffer_descriptor.h
new file mode 100644
index 0000000..d55ce3d
--- /dev/null
+++ b/lib/libucsi/mpeg/multiplex_buffer_descriptor.h
@@ -0,0 +1,65 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_MULTIPLEX_BUFFER_DESCRIPTOR
+#define _UCSI_MPEG_MULTIPLEX_BUFFER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_multiplex_buffer_descriptor descriptor.
+ */
+struct mpeg_multiplex_buffer_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint64_t mb_buffer_size : 24; ,
+ uint64_t tb_leak_rate : 24; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_multiplex_buffer_descriptor.
+ *
+ * @param d Pointer to generic descriptor structure.
+ * @return Pointer to an mpeg_multiplex_buffer_descriptor structure, or NULL on
+ * error.
+ */
+static inline struct mpeg_multiplex_buffer_descriptor*
+ mpeg_multiplex_buffer_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_multiplex_buffer_descriptor) - 2))
+ return NULL;
+
+ bswap48((uint8_t*) d + 2);
+
+ return (struct mpeg_multiplex_buffer_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/multiplex_buffer_utilization_descriptor.h b/lib/libucsi/mpeg/multiplex_buffer_utilization_descriptor.h
new file mode 100644
index 0000000..16550ed
--- /dev/null
+++ b/lib/libucsi/mpeg/multiplex_buffer_utilization_descriptor.h
@@ -0,0 +1,67 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_MULTIPLEX_BUFFER_UTILIZATION_DESCRIPTOR
+#define _UCSI_MPEG_MULTIPLEX_BUFFER_UTILIZATION_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_multiplex_buffer_utilization_descriptor structure.
+ */
+struct mpeg_multiplex_buffer_utilization_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint16_t bound_valid_flag : 1; ,
+ uint16_t ltw_offset_lower_bound : 15; );
+ EBIT2(uint16_t reserved : 1; ,
+ uint16_t ltw_offset_upper_bound : 15; );
+} __ucsi_packed;
+
+/**
+ * Process a mpeg_multiplex_buffer_utilization_descriptor.
+ *
+ * @param d Generic descriptor pointer.
+ * @return mpeg_multiplex_buffer_utilization_descriptor pointer, or NULL on error.
+ */
+static inline struct mpeg_multiplex_buffer_utilization_descriptor*
+ mpeg_multiplex_buffer_utilization_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_multiplex_buffer_utilization_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+ bswap16((uint8_t*) d + 4);
+
+ return (struct mpeg_multiplex_buffer_utilization_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/muxcode_descriptor.h b/lib/libucsi/mpeg/muxcode_descriptor.h
new file mode 100644
index 0000000..6bed334
--- /dev/null
+++ b/lib/libucsi/mpeg/muxcode_descriptor.h
@@ -0,0 +1,82 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_MUXCODE_DESCRIPTOR
+#define _UCSI_MPEG_MUXCODE_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_muxcode_descriptor structure
+ */
+struct mpeg_muxcode_descriptor {
+ struct descriptor d;
+
+ /* uint8_t entries[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_muxcode_descriptor.
+ *
+ * @param d Pointer to a generic descriptor structure.
+ * @return Pointer to an mpeg_muxcode_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_muxcode_descriptor*
+ mpeg_muxcode_descriptor_codec(struct descriptor* d)
+{
+ return (struct mpeg_muxcode_descriptor*) d;
+}
+
+/**
+ * Retrieve pointer to entries field of an mpeg_muxcode_descriptor structure.
+ *
+ * @param d Generic descriptor structure.
+ * @return Pointer to the entries field.
+ */
+static inline uint8_t *
+ mpeg_muxcode_descriptor_entries(struct mpeg_muxcode_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct mpeg_muxcode_descriptor);
+}
+
+/**
+ * Determine length of entries field of an mpeg_muxcode_descriptor structure.
+ *
+ * @param d Generic descriptor structure.
+ * @return Number of bytes in the entries field.
+ */
+static inline int
+ mpeg_muxcode_descriptor_entries_length(struct mpeg_muxcode_descriptor *d)
+{
+ return d->d.len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/odsmt_section.c b/lib/libucsi/mpeg/odsmt_section.c
new file mode 100644
index 0000000..07407f2
--- /dev/null
+++ b/lib/libucsi/mpeg/odsmt_section.c
@@ -0,0 +1,80 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/odsmt_section.h>
+
+struct mpeg_odsmt_section *mpeg_odsmt_section_codec(struct section_ext * ext)
+{
+ struct mpeg_odsmt_section * odsmt = (struct mpeg_odsmt_section *)ext;
+ uint8_t * buf = (uint8_t *)ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+ int i;
+
+ if (len < sizeof(struct mpeg_odsmt_section))
+ return NULL;
+
+ pos++;
+
+ if (odsmt->stream_count == 0) {
+ struct mpeg_odsmt_stream * stream =
+ (struct mpeg_odsmt_stream *) (buf + pos);
+
+ if ((pos + sizeof(struct mpeg_odsmt_stream_single)) > len)
+ return NULL;
+
+ bswap16(buf+pos);
+ pos+=3;
+
+ if ((pos + stream->u.single.es_info_length) >= len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, stream->u.single.es_info_length))
+ return NULL;
+
+ pos += stream->u.single.es_info_length;
+ } else {
+ for (i=0; i< odsmt->stream_count; i++) {
+ struct mpeg_odsmt_stream * stream =
+ (struct mpeg_odsmt_stream *)(buf + pos);
+
+ if ((pos + sizeof(struct mpeg_odsmt_stream_multi)) > len)
+ return NULL;
+
+ bswap16(buf+pos);
+ pos += sizeof(struct mpeg_odsmt_stream_multi);
+
+ if ((pos + stream->u.multi.es_info_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos,
+ stream->u.multi.es_info_length))
+ return NULL;
+
+ pos += stream->u.multi.es_info_length;
+ }
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct mpeg_odsmt_section *) ext;
+}
diff --git a/lib/libucsi/mpeg/odsmt_section.h b/lib/libucsi/mpeg/odsmt_section.h
new file mode 100644
index 0000000..4e01085
--- /dev/null
+++ b/lib/libucsi/mpeg/odsmt_section.h
@@ -0,0 +1,224 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_ODSMT_SECTION_H
+#define _UCSI_MPEG_ODSMT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * mpeg_odsmt_section structure.
+ */
+struct mpeg_odsmt_section {
+ struct section_ext head;
+
+ uint8_t stream_count;
+ /* stream_count==0 => struct mpeg_odsmt_stream_single streams
+ stream_count>0 => struct mpeg_odsmt_stream_multi streams[] */
+ /* uint8_t object_descriptors[] */
+} __ucsi_packed;
+
+struct mpeg_odsmt_stream_single
+{
+ uint16_t esid;
+ uint8_t es_info_length;
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+struct mpeg_odsmt_stream_multi
+{
+ uint16_t esid;
+ uint8_t fmc;
+ uint8_t es_info_length;
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Structure describing the stream information held in an mpeg_odsmt_section.
+ */
+struct mpeg_odsmt_stream {
+ union {
+ struct mpeg_odsmt_stream_single single;
+ struct mpeg_odsmt_stream_multi multi;
+ } u;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_odsmt_section.
+ *
+ * @param section Pointer to the generic section_ext structure.
+ * @return Pointer to a mpeg_odsmt_section structure, or NULL on error.
+ */
+extern struct mpeg_odsmt_section *mpeg_odsmt_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the PID field of an ODSMT.
+ *
+ * @param odsmt odsmt pointer.
+ * @return The pid.
+ */
+static inline uint16_t mpeg_odsmt_section_pid(struct mpeg_odsmt_section *odsmt)
+{
+ return odsmt->head.table_id_ext & 0x1fff;
+}
+
+/**
+ * Convenience iterator for the streams field of an mpeg_odsmt_section.
+ *
+ * @param osdmt Pointer to the mpeg_odsmt_section structure.
+ * @param pos Variable holding pointer to the current mpeg_odsmt_stream structure.
+ * @param index Variable holding the stream index.
+ */
+#define mpeg_odsmt_section_streams_for_each(osdmt, pos, index) \
+ for (index=0, (pos) = mpeg_odsmt_section_streams_first(odsmt); \
+ (pos); \
+ (pos) = mpeg_odsmt_section_streams_next(odsmt, pos, ++index))
+
+/**
+ * Convenience iterator for the descriptors field of an mpeg_odsmt_stream.
+ *
+ * @param osdmt Pointer to the mpeg_odsmt_section structure.
+ * @param stream Pointer to the mpeg_odsmt_stream structure.
+ * @param pos Variable holding pointer to the current descriptor structure.
+ */
+#define mpeg_odsmt_stream_descriptors_for_each(osdmt, stream, pos) \
+ for ((pos) = mpeg_odsmt_stream_descriptors_first(odsmt, stream); \
+ (pos); \
+ (pos) = mpeg_odsmt_stream_descriptors_next(odsmt, stream, pos))
+
+/**
+ * Retrieve a pointer to the object_descriptors field of an mpeg_odsmt_section.
+ *
+ * @param osdmt Pointer to the mpeg_odsmt_section structure.
+ * @param len On return, will contain the number of bytes in the object descriptors field.
+ * @return Pointer to the object_descriptors field, or NULL on error.
+ */
+static inline uint8_t*
+ mpeg_odsmt_section_object_descriptors(struct mpeg_odsmt_section * odsmt,
+ size_t* len);
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct mpeg_odsmt_stream *
+ mpeg_odsmt_section_streams_first(struct mpeg_odsmt_section *odsmt)
+{
+ size_t pos = sizeof(struct mpeg_odsmt_section);
+
+ if (pos >= section_ext_length(&odsmt->head))
+ return NULL;
+
+ return (struct mpeg_odsmt_stream *) ((uint8_t *) odsmt + pos);
+}
+
+static inline struct mpeg_odsmt_stream *
+ mpeg_odsmt_section_streams_next(struct mpeg_odsmt_section *odsmt,
+ struct mpeg_odsmt_stream *pos,
+ int _index)
+{
+ uint8_t *end = (uint8_t*) odsmt + section_ext_length(&odsmt->head);
+ uint8_t *next;
+
+ if (_index > odsmt->stream_count)
+ return NULL;
+
+ next = (uint8_t *) pos + sizeof(struct mpeg_odsmt_stream_multi) +
+ pos->u.multi.es_info_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct mpeg_odsmt_stream *) next;
+}
+
+static inline struct descriptor *
+ mpeg_odsmt_stream_descriptors_first(struct mpeg_odsmt_section *odsmt,
+ struct mpeg_odsmt_stream *stream)
+{
+ if (odsmt->stream_count == 0) {
+ if (stream->u.single.es_info_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t*) stream + sizeof(struct mpeg_odsmt_stream_single));
+ } else {
+ if (stream->u.multi.es_info_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t*) stream + sizeof(struct mpeg_odsmt_stream_multi));
+ }
+}
+
+static inline struct descriptor *
+ mpeg_odsmt_stream_descriptors_next(struct mpeg_odsmt_section *odsmt,
+ struct mpeg_odsmt_stream *stream,
+ struct descriptor* pos)
+{
+ if (odsmt->stream_count == 0) {
+ return next_descriptor((uint8_t *) stream + sizeof(struct mpeg_odsmt_stream_single),
+ stream->u.single.es_info_length,
+ pos);
+ } else {
+ return next_descriptor((uint8_t *) stream + sizeof(struct mpeg_odsmt_stream_multi),
+ stream->u.multi.es_info_length,
+ pos);
+ }
+}
+
+static inline uint8_t*
+ mpeg_odsmt_section_object_descriptors(struct mpeg_odsmt_section * odsmt,
+ size_t* len)
+{
+ struct mpeg_odsmt_stream* pos;
+ size_t size = sizeof(struct mpeg_odsmt_section);
+ int _index;
+
+ mpeg_odsmt_section_streams_for_each(odsmt, pos, _index) {
+ if (odsmt->stream_count == 0)
+ size += sizeof(struct mpeg_odsmt_stream_single) +
+ pos->u.single.es_info_length;
+ else
+ size += sizeof(struct mpeg_odsmt_stream_multi) +
+ pos->u.multi.es_info_length;
+ }
+
+ *len = section_ext_length(&odsmt->head) - size;
+ return (uint8_t*) odsmt + size;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/pat_section.c b/lib/libucsi/mpeg/pat_section.c
new file mode 100644
index 0000000..2e4c2cc
--- /dev/null
+++ b/lib/libucsi/mpeg/pat_section.c
@@ -0,0 +1,46 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/pat_section.h>
+
+struct mpeg_pat_section *mpeg_pat_section_codec(struct section_ext * ext)
+{
+ uint8_t *buf = (uint8_t *)ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct mpeg_pat_section))
+ return NULL;
+
+ while (pos < len) {
+ if ((pos + 4) > len)
+ return NULL;
+
+ bswap16(buf + pos);
+ bswap16(buf + pos + 2);
+ pos += 4;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct mpeg_pat_section *)ext;
+}
diff --git a/lib/libucsi/mpeg/pat_section.h b/lib/libucsi/mpeg/pat_section.h
new file mode 100644
index 0000000..eadfe28
--- /dev/null
+++ b/lib/libucsi/mpeg/pat_section.h
@@ -0,0 +1,118 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_PAT_SECTION_H
+#define _UCSI_MPEG_PAT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * mpeg_pat_section structure.
+ */
+struct mpeg_pat_section {
+ struct section_ext head; /* table_id_ext == transport_stream_id */
+
+ /* struct mpeg_pat_program programs[] */
+} __ucsi_packed;
+
+/**
+ * A program within an mpeg_pat_section.
+ */
+struct mpeg_pat_program {
+ uint16_t program_number;
+ EBIT2(uint16_t reserved : 3; ,
+ uint16_t pid :13; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_pat_section.
+ *
+ * @param section Pointer to the generic section_ext structure.
+ * @return Pointer to the mpeg_pat_section structure, or NULL on error.
+ */
+extern struct mpeg_pat_section *mpeg_pat_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for the transport_stream_id field of a PAT.
+ *
+ * @param pat PAT pointer.
+ * @return The transport_stream_id.
+ */
+static inline uint16_t mpeg_pat_section_transport_stream_id(struct mpeg_pat_section *pat)
+{
+ return pat->head.table_id_ext;
+}
+
+/**
+ * Conveience iterator for the programs field of an mpeg_pat_section.
+ *
+ * @param pat Pointer to the mpeg_pat_section structure.
+ * @param pos Variable holding a pointer to the current mpeg_pat_program structure.
+ */
+#define mpeg_pat_section_programs_for_each(pat, pos) \
+ for ((pos) = mpeg_pat_section_programs_first(pat); \
+ (pos); \
+ (pos) = mpeg_pat_section_programs_next(pat, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct mpeg_pat_program *
+ mpeg_pat_section_programs_first(struct mpeg_pat_section * pat)
+{
+ size_t pos = sizeof(struct mpeg_pat_section);
+
+ if (pos >= section_ext_length(&pat->head))
+ return NULL;
+
+ return (struct mpeg_pat_program*)((uint8_t *) pat + pos);
+}
+
+static inline
+ struct mpeg_pat_program *mpeg_pat_section_programs_next(struct mpeg_pat_section * pat,
+ struct mpeg_pat_program * pos)
+{
+ uint8_t *end = (uint8_t*) pat + section_ext_length(&pat->head);
+ uint8_t *next= (uint8_t *) pos + sizeof(struct mpeg_pat_program);
+
+ if (next >= end)
+ return NULL;
+
+ return (struct mpeg_pat_program *) next;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/pmt_section.c b/lib/libucsi/mpeg/pmt_section.c
new file mode 100644
index 0000000..e5aec6a
--- /dev/null
+++ b/lib/libucsi/mpeg/pmt_section.c
@@ -0,0 +1,71 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/pmt_section.h>
+
+struct mpeg_pmt_section * mpeg_pmt_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *) ext;
+ struct mpeg_pmt_section * pmt = (struct mpeg_pmt_section *) ext;
+ size_t pos = sizeof(struct section_ext);
+ size_t len = section_ext_length(ext);
+
+ if (len < sizeof(struct mpeg_pmt_section))
+ return NULL;
+
+ bswap16(buf + pos);
+ pos += 2;
+ bswap16(buf + pos);
+ pos += 2;
+
+ if ((pos + pmt->program_info_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, pmt->program_info_length))
+ return NULL;
+
+ pos += pmt->program_info_length;
+
+ while (pos < len) {
+ struct mpeg_pmt_stream * stream =
+ (struct mpeg_pmt_stream *) (buf + pos);
+
+ if ((pos + sizeof(struct mpeg_pmt_stream)) > len)
+ return NULL;
+
+ bswap16(buf + pos + 1);
+ bswap16(buf + pos + 3);
+ pos += sizeof(struct mpeg_pmt_stream);
+
+ if ((pos + stream->es_info_length) > len)
+ return NULL;
+
+ if (verify_descriptors(buf + pos, stream->es_info_length))
+ return NULL;
+
+ pos += stream->es_info_length;
+ }
+
+ if (pos != len)
+ return NULL;
+
+ return (struct mpeg_pmt_section *) ext;
+}
diff --git a/lib/libucsi/mpeg/pmt_section.h b/lib/libucsi/mpeg/pmt_section.h
new file mode 100644
index 0000000..03dea1b
--- /dev/null
+++ b/lib/libucsi/mpeg/pmt_section.h
@@ -0,0 +1,188 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_PMT_SECTION_H
+#define _UCSI_MPEG_PMT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * mpeg_pmt_section structure.
+ */
+struct mpeg_pmt_section {
+ struct section_ext head;
+
+ EBIT2(uint16_t reserved_1 : 3; ,
+ uint16_t pcr_pid :13; );
+ EBIT2(uint16_t reserved_2 : 4; ,
+ uint16_t program_info_length :12; );
+ /* struct descriptor descriptors[] */
+ /* struct mpeg_pmt_stream streams[] */
+} __ucsi_packed;
+
+/**
+ * A stream within an mpeg_pmt_section.
+ */
+struct mpeg_pmt_stream {
+ uint8_t stream_type;
+ EBIT2(uint16_t reserved_1 : 3; ,
+ uint16_t pid :13; );
+ EBIT2(uint16_t reserved_2 : 4; ,
+ uint16_t es_info_length :12; );
+
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_pmt_section section.
+ *
+ * @param section Pointer to the generic section header.
+ * @return Pointer to the mpeg_pmt_section structure, or NULL on error.
+ */
+extern struct mpeg_pmt_section *mpeg_pmt_section_codec(struct section_ext *section);
+
+/**
+ * Accessor for program_number field of a PMT.
+ *
+ * @param pmt PMT pointer.
+ * @return The program_number.
+ */
+static inline uint16_t mpeg_pmt_section_program_number(struct mpeg_pmt_section *pmt)
+{
+ return pmt->head.table_id_ext;
+}
+
+/**
+ * Convenience iterator for the descriptors field of the mpeg_pmt_section structure.
+ *
+ * @param pmt Pointer to the mpeg_pmt_section structure.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define mpeg_pmt_section_descriptors_for_each(pmt, pos) \
+ for ((pos) = mpeg_pmt_section_descriptors_first(pmt); \
+ (pos); \
+ (pos) = mpeg_pmt_section_descriptors_next(pmt, pos))
+
+/**
+ * Convenience iterator for the streams field of the mpeg_pmt_section structure.
+ *
+ * @param pmt Pointer to the mpeg_pmt_section structure.
+ * @param pos Variable holding a pointer to the current mpeg_pmt_stream.
+ */
+#define mpeg_pmt_section_streams_for_each(pmt, pos) \
+ for ((pos) = mpeg_pmt_section_streams_first(pmt); \
+ (pos); \
+ (pos) = mpeg_pmt_section_streams_next(pmt, pos))
+
+/**
+ * Convenience iterator for the descriptors field of an mpeg_pmt_stream structure.
+ *
+ * @param stream Pointer to the mpeg_pmt_stream structure.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define mpeg_pmt_stream_descriptors_for_each(stream, pos) \
+ for ((pos) = mpeg_pmt_stream_descriptors_first(stream); \
+ (pos); \
+ (pos) = mpeg_pmt_stream_descriptors_next(stream, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ mpeg_pmt_section_descriptors_first(struct mpeg_pmt_section * pmt)
+{
+ if (pmt->program_info_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t *) pmt + sizeof(struct mpeg_pmt_section));
+}
+
+static inline struct descriptor *
+ mpeg_pmt_section_descriptors_next(struct mpeg_pmt_section *pmt,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t *) pmt + sizeof(struct mpeg_pmt_section),
+ pmt->program_info_length,
+ pos);
+}
+
+static inline struct mpeg_pmt_stream *
+ mpeg_pmt_section_streams_first(struct mpeg_pmt_section * pmt)
+{
+ size_t pos = sizeof(struct mpeg_pmt_section) + pmt->program_info_length;
+
+ if (pos >= section_ext_length(&pmt->head))
+ return NULL;
+
+ return (struct mpeg_pmt_stream *)((uint8_t *)pmt + pos);
+}
+
+static inline struct mpeg_pmt_stream *
+ mpeg_pmt_section_streams_next(struct mpeg_pmt_section * pmt,
+ struct mpeg_pmt_stream * pos)
+{
+ uint8_t *end = (uint8_t*) pmt + section_ext_length(&pmt->head);
+ uint8_t *next = (uint8_t *) pos + sizeof(struct mpeg_pmt_stream) +
+ pos->es_info_length;
+
+ if (next >= end)
+ return NULL;
+
+ return (struct mpeg_pmt_stream *) next;
+}
+
+static inline struct descriptor *
+ mpeg_pmt_stream_descriptors_first(struct mpeg_pmt_stream *stream)
+{
+ if (stream->es_info_length == 0)
+ return NULL;
+
+ return (struct descriptor *)
+ ((uint8_t*) stream + sizeof(struct mpeg_pmt_stream));
+}
+
+static inline struct descriptor *
+ mpeg_pmt_stream_descriptors_next(struct mpeg_pmt_stream *stream,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t *) stream + sizeof(struct mpeg_pmt_stream),
+ stream->es_info_length,
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/private_data_indicator_descriptor.h b/lib/libucsi/mpeg/private_data_indicator_descriptor.h
new file mode 100644
index 0000000..80e8ef3
--- /dev/null
+++ b/lib/libucsi/mpeg/private_data_indicator_descriptor.h
@@ -0,0 +1,63 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_PRIVATE_DATA_INDICATOR_DESCRIPTOR
+#define _UCSI_MPEG_PRIVATE_DATA_INDICATOR_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_private_data_indicator_descriptor structure
+ */
+struct mpeg_private_data_indicator_descriptor {
+ struct descriptor d;
+
+ uint32_t private_data_indicator;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_private_data_indicator_descriptor structure.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_private_data_indicator_descriptor, or NULL on error.
+ */
+static inline struct mpeg_private_data_indicator_descriptor*
+ mpeg_private_data_indicator_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_private_data_indicator_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+
+ return (struct mpeg_private_data_indicator_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/registration_descriptor.h b/lib/libucsi/mpeg/registration_descriptor.h
new file mode 100644
index 0000000..df5c186
--- /dev/null
+++ b/lib/libucsi/mpeg/registration_descriptor.h
@@ -0,0 +1,91 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_REGISTRATION_DESCRIPTOR
+#define _UCSI_MPEG_REGISTRATION_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_registration_descriptor structure.
+ */
+struct mpeg_registration_descriptor {
+ struct descriptor d;
+
+ uint32_t format_identifier;
+ /* uint8_t additional_id_info[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_registration_descriptor.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_registration_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_registration_descriptor*
+ mpeg_registration_descriptor_codec(struct descriptor* d)
+{
+ if (d->len < (sizeof(struct mpeg_registration_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+
+ return (struct mpeg_registration_descriptor*) d;
+}
+
+/**
+ * Retrieve a pointer to the additional_id_info field of the
+ * mpeg_registration_descriptor structure.
+ *
+ * @param d Pointer to the mpeg_registration_descriptor structure.
+ * @return Pointer to the field.
+ */
+static inline uint8_t *
+ mpeg_registration_descriptor_additional_id_info(struct mpeg_registration_descriptor *d)
+{
+ return (uint8_t *) d + sizeof(struct mpeg_registration_descriptor);
+}
+
+/**
+ * Determine number of bytes in the additional_id_info field of the
+ * mpeg_registration_descriptor structure.
+ *
+ * @param d Pointer to the mpeg_registration_descriptor structure.
+ * @return Number of bytes.
+ */
+
+static inline int
+ mpeg_registration_descriptor_additional_id_info_length(struct mpeg_registration_descriptor *d)
+{
+ return d->d.len - 4;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/section.h b/lib/libucsi/mpeg/section.h
new file mode 100644
index 0000000..7dbff93
--- /dev/null
+++ b/lib/libucsi/mpeg/section.h
@@ -0,0 +1,58 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_SECTION_H
+#define _UCSI_MPEG_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/mpeg/cat_section.h>
+#include <libucsi/mpeg/odsmt_section.h>
+#include <libucsi/mpeg/pat_section.h>
+#include <libucsi/mpeg/pmt_section.h>
+#include <libucsi/mpeg/tsdt_section.h>
+#include <libucsi/mpeg/metadata_section.h>
+
+#define TRANSPORT_PAT_PID 0x00
+#define TRANSPORT_CAT_PID 0x01
+#define TRANSPORT_TSDT_PID 0x02
+
+/**
+ * Enumeration of MPEG section tags.
+ */
+enum mpeg_section_tag {
+ stag_mpeg_program_association = 0x00,
+ stag_mpeg_conditional_access = 0x01,
+ stag_mpeg_program_map = 0x02,
+ stag_mpeg_transport_stream_description = 0x03,
+ stag_mpeg_iso14496_scene_description = 0x04,
+ stag_mpeg_iso14496_object_description = 0x05,
+ stag_mpeg_metadata = 0x06,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/sl_descriptor.h b/lib/libucsi/mpeg/sl_descriptor.h
new file mode 100644
index 0000000..ab086e3
--- /dev/null
+++ b/lib/libucsi/mpeg/sl_descriptor.h
@@ -0,0 +1,63 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_SL_DESCRIPTOR
+#define _UCSI_MPEG_SL_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_sl_descriptor structure.
+ */
+struct mpeg_sl_descriptor {
+ struct descriptor d;
+
+ uint16_t es_id;
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_sl_descriptor.
+ *
+ * @param d The generic descriptor structure.
+ * @return Pointer to an mpeg_sl_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_sl_descriptor*
+ mpeg_sl_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_sl_descriptor) - 2))
+ return NULL;
+
+ bswap16((uint8_t*) d + 2);
+
+ return (struct mpeg_sl_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/smoothing_buffer_descriptor.h b/lib/libucsi/mpeg/smoothing_buffer_descriptor.h
new file mode 100644
index 0000000..5e6ad33
--- /dev/null
+++ b/lib/libucsi/mpeg/smoothing_buffer_descriptor.h
@@ -0,0 +1,66 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_SMOOTHING_BUFFER_DESCRIPTOR
+#define _UCSI_MPEG_SMOOTHING_BUFFER_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_smoothing_buffer_descriptor structure.
+ */
+struct mpeg_smoothing_buffer_descriptor {
+ struct descriptor d;
+
+ EBIT4(uint64_t reserved_1 : 2; ,
+ uint64_t sb_leak_rate :22; ,
+ uint64_t reserved_2 : 2; ,
+ uint64_t sb_size :22; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_smoothing_buffer_descriptor.
+ *
+ * @param d The generic descriptor structure.
+ * @return Pointer to mpeg_smoothing_buffer_descriptor, or NULL on error.
+ */
+static inline struct mpeg_smoothing_buffer_descriptor*
+ mpeg_smoothing_buffer_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_smoothing_buffer_descriptor) - 2))
+ return NULL;
+
+ bswap48((uint8_t*) d + 2);
+
+ return (struct mpeg_smoothing_buffer_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/std_descriptor.h b/lib/libucsi/mpeg/std_descriptor.h
new file mode 100644
index 0000000..2625a41
--- /dev/null
+++ b/lib/libucsi/mpeg/std_descriptor.h
@@ -0,0 +1,62 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_STD_DESCRIPTOR
+#define _UCSI_MPEG_STD_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_std_descriptor structure.
+ */
+struct mpeg_std_descriptor {
+ struct descriptor d;
+
+ EBIT2(uint8_t reserved : 7; ,
+ uint8_t leak_valid_flag : 1; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_std_descriptor.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_std_descriptor, or NULL on error.
+ */
+static inline struct mpeg_std_descriptor*
+ mpeg_std_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_std_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg_std_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/system_clock_descriptor.h b/lib/libucsi/mpeg/system_clock_descriptor.h
new file mode 100644
index 0000000..681641f
--- /dev/null
+++ b/lib/libucsi/mpeg/system_clock_descriptor.h
@@ -0,0 +1,65 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_SYSTEM_CLOCK_DESCRIPTOR
+#define _UCSI_MPEG_SYSTEM_CLOCK_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_system_clock_descriptor structure.
+ */
+struct mpeg_system_clock_descriptor {
+ struct descriptor d;
+
+ EBIT3(uint8_t external_clock_reference_indicator : 1; ,
+ uint8_t reserved_1 : 1; ,
+ uint8_t clock_accuracy_integer : 6; );
+ EBIT2(uint8_t clock_accuracy_exponent : 3; ,
+ uint8_t reserved_2 : 5; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_system_clock_descriptor.
+ *
+ * @param d The generic descriptor structure.
+ * @return Pointer to a mpeg_system_clock_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_system_clock_descriptor*
+ mpeg_system_clock_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_system_clock_descriptor) - 2))
+ return NULL;
+
+ return (struct mpeg_system_clock_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/target_background_grid_descriptor.h b/lib/libucsi/mpeg/target_background_grid_descriptor.h
new file mode 100644
index 0000000..7394e82
--- /dev/null
+++ b/lib/libucsi/mpeg/target_background_grid_descriptor.h
@@ -0,0 +1,66 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_TARGET_BACKGROUND_GRID_DESCRIPTOR
+#define _UCSI_MPEG_TARGET_BACKGROUND_GRID_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * mpeg_target_background_grid_descriptor structure.
+ */
+struct mpeg_target_background_grid_descriptor {
+ struct descriptor d;
+
+ EBIT3(uint32_t horizontal_size : 14; ,
+ uint32_t vertical_size : 14; ,
+ uint32_t aspect_ratio_information : 4; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_target_background_grid_descriptor structure.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_target_background_grid_descriptor structure, or
+ * NULL on error.
+ */
+static inline struct mpeg_target_background_grid_descriptor*
+ mpeg_target_background_grid_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_target_background_grid_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+
+ return (struct mpeg_target_background_grid_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/tsdt_section.c b/lib/libucsi/mpeg/tsdt_section.c
new file mode 100644
index 0000000..fec9dd7
--- /dev/null
+++ b/lib/libucsi/mpeg/tsdt_section.c
@@ -0,0 +1,34 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/tsdt_section.h>
+
+struct mpeg_tsdt_section * mpeg_tsdt_section_codec(struct section_ext * ext)
+{
+ uint8_t * buf = (uint8_t *)ext;
+ size_t pos = sizeof(struct section_ext);
+
+ if (verify_descriptors(buf + pos,
+ section_ext_length(ext) - sizeof(struct mpeg_tsdt_section)))
+ return NULL;
+
+ return (struct mpeg_tsdt_section *)ext;
+}
diff --git a/lib/libucsi/mpeg/tsdt_section.h b/lib/libucsi/mpeg/tsdt_section.h
new file mode 100644
index 0000000..2bbae02
--- /dev/null
+++ b/lib/libucsi/mpeg/tsdt_section.h
@@ -0,0 +1,94 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_TSDT_SECTION_H
+#define _UCSI_MPEG_TSDT_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/section.h>
+
+/**
+ * mpeg_tsdt_section structure.
+ */
+struct mpeg_tsdt_section {
+ struct section_ext head;
+
+ /* struct descriptor descriptors[] */
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_tsdt_section structure.
+ *
+ * @param section Pointer to the section_ext structure.
+ * @return Pointer to the mpeg_tsdt_section structure, or NULL on error.
+ */
+extern struct mpeg_tsdt_section *mpeg_tsdt_section_codec(struct section_ext *section);
+
+/**
+ * Convenience iterator for descriptors field.
+ *
+ * @param tsdt Pointer to the mpeg_tsdt_section structure.
+ * @param pos Variable holding a pointer to the current descriptor.
+ */
+#define mpeg_tsdt_section_descriptors_for_each(tsdt, pos) \
+ for ((pos) = mpeg_tsdt_section_descriptors_first(tsdt); \
+ (pos); \
+ (pos) = mpeg_tsdt_section_descriptors_next(tsdt, pos))
+
+
+
+
+
+
+
+
+
+
+/******************************** PRIVATE CODE ********************************/
+static inline struct descriptor *
+ mpeg_tsdt_section_descriptors_first(struct mpeg_tsdt_section * tsdt)
+{
+ size_t pos = sizeof(struct mpeg_tsdt_section);
+
+ if (pos >= section_ext_length(&tsdt->head))
+ return NULL;
+
+ return (struct descriptor*)((uint8_t *) tsdt + pos);
+}
+
+static inline struct descriptor *
+ mpeg_tsdt_section_descriptors_next(struct mpeg_tsdt_section *tsdt,
+ struct descriptor* pos)
+{
+ return next_descriptor((uint8_t *) tsdt + sizeof(struct mpeg_tsdt_section),
+ section_ext_length(&tsdt->head) - sizeof(struct mpeg_tsdt_section),
+ pos);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/types.h b/lib/libucsi/mpeg/types.h
new file mode 100644
index 0000000..300cb23
--- /dev/null
+++ b/lib/libucsi/mpeg/types.h
@@ -0,0 +1,127 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_TYPES_H
+#define _UCSI_MPEG_TYPES_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Known stream types.
+ */
+enum {
+ MPEG_STREAM_TYPE_ISO11172_VIDEO = 0x01,
+ MPEG_STREAM_TYPE_ISO13818_2_VIDEO = 0x02,
+ MPEG_STREAM_TYPE_ISO11172_AUDIO = 0x03,
+ MPEG_STREAM_TYPE_ISO13818_3_AUDIO = 0x04,
+ MPEG_STREAM_TYPE_ISO13818_1_PRIVATE_SECTIONS = 0x05,
+ MPEG_STREAM_TYPE_ISO13818_1_PRIVATE_PES = 0x06,
+ MPEG_STREAM_TYPE_ISO13522_MHEG = 0x07,
+ MPEG_STREAM_TYPE_ISO13818_DSMCC = 0x08,
+ MPEG_STREAM_TYPE_ITUH222_1 = 0x09,
+ MPEG_STREAM_TYPE_ISO13818_6_A = 0x0a,
+ MPEG_STREAM_TYPE_ISO13818_6_B = 0x0b,
+ MPEG_STREAM_TYPE_ISO13818_6_C = 0x0c,
+ MPEG_STREAM_TYPE_ISO13818_6_D = 0x0d,
+ MPEG_STREAM_TYPE_ISO13818_1_AUX = 0x0e,
+ MPEG_STREAM_TYPE_ISO13818_7_AUDIO_ADTS = 0x0f,
+ MPEG_STREAM_TYPE_ISO14496_2_VISUAL = 0x10,
+ MPEG_STREAM_TYPE_ISO14496_3_AUDIO_LATM = 0x11,
+ MPEG_STREAM_TYPE_ISO14496_1_PES = 0x12,
+ MPEG_STREAM_TYPE_ISO14496_1_SECTIONS = 0x13,
+ MPEG_STREAM_TYPE_ISO14496_6_SYNCDOWNLOAD = 0x14,
+ MPEG_STREAM_TYPE_METADATA_PES = 0x15,
+ MPEG_STREAM_TYPE_METADATA_SECTIONS = 0x16,
+ MPEG_STREAM_TYPE_METADATA_DSMCC_DATA = 0x17,
+ MPEG_STREAM_TYPE_METADATA_DSMCC_OBJECT = 0x18,
+ MPEG_STREAM_TYPE_METADATA_SYNCDOWNLOAD = 0x19,
+};
+
+/**
+ * Metadata formats
+ */
+enum {
+ MPEG_METADATA_FORMAT_ISO15938_1_TEM = 0x01,
+ MPEG_METADATA_FORMAT_ISO15938_1_BIM = 0x02,
+ MPEG_METADATA_FORMAT_METADATA_APPLICATION_FORMAT = 0x3F,
+ MPEG_METADATA_FORMAT_METADATA_APPLICATION_FORMAT_ID = 0xFF,
+};
+
+/**
+ * MPEG 4 audio profile and levels.
+ */
+enum {
+ MPEG4_AUDIO_PROFILE_MAIN_LEVEL_1 = 0x10,
+ MPEG4_AUDIO_PROFILE_MAIN_LEVEL_2 = 0x11,
+ MPEG4_AUDIO_PROFILE_MAIN_LEVEL_3 = 0x12,
+ MPEG4_AUDIO_PROFILE_MAIN_LEVEL_4 = 0x13,
+
+ MPEG4_AUDIO_PROFILE_SCALABLE_LEVEL_1 = 0x18,
+ MPEG4_AUDIO_PROFILE_SCALABLE_LEVEL_2 = 0x19,
+ MPEG4_AUDIO_PROFILE_SCALABLE_LEVEL_3 = 0x1a,
+ MPEG4_AUDIO_PROFILE_SCALABLE_LEVEL_4 = 0x1b,
+
+ MPEG4_AUDIO_PROFILE_SPEECH_LEVEL_1 = 0x20,
+ MPEG4_AUDIO_PROFILE_SPEECH_LEVEL_2 = 0x21,
+
+ MPEG4_AUDIO_PROFILE_SYNTHESIS_LEVEL_1 = 0x28,
+ MPEG4_AUDIO_PROFILE_SYNTHESIS_LEVEL_2 = 0x29,
+ MPEG4_AUDIO_PROFILE_SYNTHESIS_LEVEL_3 = 0x2a,
+
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_1 = 0x30,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_2 = 0x31,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_3 = 0x32,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_4 = 0x33,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_5 = 0x34,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_6 = 0x35,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_7 = 0x36,
+ MPEG4_AUDIO_PROFILE_HQ_LEVEL_8 = 0x37,
+
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_1 = 0x38,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_2 = 0x39,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_3 = 0x3a,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_4 = 0x3b,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_5 = 0x3c,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_6 = 0x3d,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_7 = 0x3e,
+ MPEG4_AUDIO_PROFILE_LOW_DELAY_LEVEL_8 = 0x3f,
+
+ MPEG4_AUDIO_PROFILE_NATURAL_LEVEL_1 = 0x40,
+ MPEG4_AUDIO_PROFILE_NATURAL_LEVEL_2 = 0x41,
+ MPEG4_AUDIO_PROFILE_NATURAL_LEVEL_3 = 0x42,
+ MPEG4_AUDIO_PROFILE_NATURAL_LEVEL_4 = 0x43,
+
+ MPEG4_AUDIO_PROFILE_MOBILE_LEVEL_1 = 0x48,
+ MPEG4_AUDIO_PROFILE_MOBILE_LEVEL_2 = 0x49,
+ MPEG4_AUDIO_PROFILE_MOBILE_LEVEL_3 = 0x4a,
+ MPEG4_AUDIO_PROFILE_MOBILE_LEVEL_4 = 0x4b,
+ MPEG4_AUDIO_PROFILE_MOBILE_LEVEL_5 = 0x4c,
+ MPEG4_AUDIO_PROFILE_MOBILE_LEVEL_6 = 0x4d,
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/video_stream_descriptor.h b/lib/libucsi/mpeg/video_stream_descriptor.h
new file mode 100644
index 0000000..14e9196
--- /dev/null
+++ b/lib/libucsi/mpeg/video_stream_descriptor.h
@@ -0,0 +1,101 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_VIDEO_STREAM_DESCRIPTOR
+#define _UCSI_MPEG_VIDEO_STREAM_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+#include <libucsi/endianops.h>
+
+/**
+ * The mpeg_video_stream_descriptor structure
+ */
+struct mpeg_video_stream_descriptor {
+ struct descriptor d;
+
+ EBIT5(uint8_t multiple_frame_rate_flag : 1; ,
+ uint8_t frame_rate_code : 4; ,
+ uint8_t mpeg_1_only_flag : 1; ,
+ uint8_t constrained_parameter_flag : 1; ,
+ uint8_t still_picture_flag : 1; );
+ /* if (mpeg_1_only_flag == 0) struct mpeg_video_stream_extra extra */
+} __ucsi_packed;
+
+/**
+ * The mpeg_video_stream_extra - only present in non-MPEG1-only streams.
+ */
+struct mpeg_video_stream_extra {
+ uint8_t profile_and_level_indication;
+ EBIT3(uint8_t chroma_format : 2; ,
+ uint8_t frame_rate_extension : 1; ,
+ uint8_t reserved : 5; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_video_stream_descriptor structure.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_video_stream_descriptor, or NULL on error.
+ */
+static inline struct mpeg_video_stream_descriptor*
+ mpeg_video_stream_descriptor_codec(struct descriptor* d)
+{
+ struct mpeg_video_stream_descriptor* vsd =
+ (struct mpeg_video_stream_descriptor*) d;
+
+ if (d->len < (sizeof(struct mpeg_video_stream_descriptor) - 2))
+ return NULL;
+
+ if (!vsd->mpeg_1_only_flag) {
+ if (d->len != (sizeof(struct mpeg_video_stream_descriptor) +
+ sizeof(struct mpeg_video_stream_extra) - 2))
+ return NULL;
+ }
+
+ return (struct mpeg_video_stream_descriptor*) d;
+}
+
+/**
+ * Get a pointer to the mpeg_video_stream_extra structure.
+ *
+ * @param d Pointer to the mpeg_video_stream_descriptor structure.
+ * @return Pointer to the mpeg_video_stream_extra structure, or NULL on error.
+ */
+static inline struct mpeg_video_stream_extra*
+ mpeg_video_stream_descriptor_extra(struct mpeg_video_stream_descriptor* d)
+{
+ if (d->mpeg_1_only_flag != 0)
+ return NULL;
+
+ return (struct mpeg_video_stream_extra*)
+ ((uint8_t*) d + sizeof(struct mpeg_video_stream_descriptor));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/mpeg/video_window_descriptor.h b/lib/libucsi/mpeg/video_window_descriptor.h
new file mode 100644
index 0000000..a9a63c7
--- /dev/null
+++ b/lib/libucsi/mpeg/video_window_descriptor.h
@@ -0,0 +1,64 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_MPEG_VIDEO_WINDOW_DESCRIPTOR
+#define _UCSI_MPEG_VIDEO_WINDOW_DESCRIPTOR 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/descriptor.h>
+
+/**
+ * mpeg_video_window_descriptor structure.
+ */
+struct mpeg_video_window_descriptor {
+ struct descriptor d;
+
+ EBIT3(uint32_t horizontal_offset : 14; ,
+ uint32_t vertical_offset : 14; ,
+ uint32_t window_priority : 4; );
+} __ucsi_packed;
+
+/**
+ * Process an mpeg_video_window_descriptor.
+ *
+ * @param d Pointer to the generic descriptor structure.
+ * @return Pointer to the mpeg_video_window_descriptor structure, or NULL on error.
+ */
+static inline struct mpeg_video_window_descriptor*
+ mpeg_video_window_descriptor_codec(struct descriptor* d)
+{
+ if (d->len != (sizeof(struct mpeg_video_window_descriptor) - 2))
+ return NULL;
+
+ bswap32((uint8_t*) d + 2);
+
+ return (struct mpeg_video_window_descriptor*) d;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/section.h b/lib/libucsi/section.h
new file mode 100644
index 0000000..53ad07f
--- /dev/null
+++ b/lib/libucsi/section.h
@@ -0,0 +1,253 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_SECTION_H
+#define _UCSI_SECTION_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libucsi/endianops.h>
+#include <libucsi/descriptor.h>
+#include <libucsi/crc32.h>
+#include <stdint.h>
+#include <string.h>
+
+#define CRC_SIZE 4
+
+
+/**
+ * Generic section header.
+ */
+struct section {
+ uint8_t table_id;
+ EBIT4(uint16_t syntax_indicator : 1; ,
+ uint16_t private_indicator : 1; , /* 2.4.4.10 */
+ uint16_t reserved : 2; ,
+ uint16_t length :12; );
+} __ucsi_packed;
+
+/**
+ * Generic extended section header structure.
+ */
+struct section_ext {
+ uint8_t table_id;
+ EBIT4(uint16_t syntax_indicator : 1; ,
+ uint16_t private_indicator : 1; , /* 2.4.4.10 */
+ uint16_t reserved : 2; ,
+ uint16_t length :12; );
+
+ uint16_t table_id_ext;
+ EBIT3(uint8_t reserved1 : 2; ,
+ uint8_t version_number : 5; ,
+ uint8_t current_next_indicator : 1; );
+ uint8_t section_number;
+ uint8_t last_section_number;
+} __ucsi_packed;
+
+/**
+ * Structure for keeping track of sections of a PSI table.
+ */
+struct psi_table_state {
+ uint8_t version_number;
+ uint16_t next_section_number;
+ uint8_t complete:1;
+ uint8_t new_table:1;
+} __ucsi_packed;
+
+
+/**
+ * Determine the total length of a section, including the header.
+ *
+ * @param section The parsed section structure.
+ * @return The length.
+ */
+static inline size_t section_length(struct section *section)
+{
+ return section->length + sizeof(struct section);
+}
+
+/**
+ * Determine the total length of an extended section, including the header,
+ * but omitting the CRC.
+ *
+ * @param section The parsed section_ext structure.
+ * @return The length.
+ */
+static inline size_t section_ext_length(struct section_ext * section)
+{
+ return section->length + sizeof(struct section) - CRC_SIZE;
+}
+
+/**
+ * Process a section structure in-place.
+ *
+ * @param buf Pointer to the data.
+ * @param len Length of data.
+ * @return Pointer to the section structure, or NULL if invalid.
+ */
+static inline struct section * section_codec(uint8_t * buf, size_t len)
+{
+ struct section * ret = (struct section *)buf;
+
+ if (len < 3)
+ return NULL;
+
+ bswap16(buf+1);
+
+ if (len != ret->length + 3U)
+ return NULL;
+
+ return ret;
+}
+
+/**
+ * Some sections have a CRC even though they are not section_exts.
+ * This function is to allow checking of them.
+ *
+ * @param section Pointer to the processed section structure.
+ * @return Nonzero on error, or 0 if the CRC was correct.
+ */
+static inline int section_check_crc(struct section *section)
+{
+ uint8_t * buf = (uint8_t *) section;
+ size_t len = section_length(section);
+ uint32_t crc;
+
+ /* the crc check has to be performed on the unswapped data */
+ bswap16(buf+1);
+ crc = crc32(CRC32_INIT, buf, len);
+ bswap16(buf+1);
+
+ /* the crc check includes the crc value,
+ * the result should therefore be zero.
+ */
+ if (crc)
+ return -1;
+ return 0;
+}
+
+
+/**
+ * Decode an extended section structure.
+ *
+ * @param section Pointer to the processed section structure.
+ * @param check_crc If 1, the CRC of the section will also be checked.
+ * @return Pointer to the parsed section_ext structure, or NULL if invalid.
+ */
+static inline struct section_ext * section_ext_decode(struct section * section,
+ int check_crc)
+{
+ if (section->syntax_indicator == 0)
+ return NULL;
+
+ if (check_crc) {
+ if (section_check_crc(section))
+ return NULL;
+ }
+
+ bswap16((uint8_t *)section + sizeof(struct section));
+
+ return (struct section_ext *)section;
+}
+
+/**
+ * Encode an extended section structure for transmission.
+ *
+ * @param section Pointer to the section_ext structure.
+ * @param update_crc If 1, the CRC of the section will also be updated.
+ * @return Pointer to the encoded section_ext structure, or NULL if invalid.
+ */
+static inline struct section_ext * section_ext_encode(struct section_ext* section,
+ int update_crc)
+{
+ if (section->syntax_indicator == 0)
+ return NULL;
+
+ bswap16((uint8_t *)section + sizeof(struct section));
+
+ if (update_crc) {
+ uint8_t * buf = (uint8_t *) section;
+ int len = sizeof(struct section) + section->length;
+ uint32_t crc;
+
+ /* the crc has to be performed on the swapped data */
+ bswap16(buf+1);
+ crc = crc32(CRC32_INIT, buf, len-4);
+ bswap16(buf+1);
+
+ /* update the CRC */
+ *((uint32_t*) (buf+len-4)) = crc;
+ bswap32(buf+len-4);
+ }
+
+ return (struct section_ext *)section;
+}
+
+/**
+ * Reset a psi_table_state structure.
+ *
+ * @param tstate The structure to reset.
+ */
+static inline void psi_table_state_reset(struct psi_table_state *tstate)
+{
+ tstate->version_number = 0xff;
+}
+
+/**
+ * Check if a supplied section_ext is something we want to process.
+ *
+ * @param section The parsed section_ext structure.
+ * @param tstate The state structure for this PSI table.
+ * @return 0=> not useful. nonzero => useful.
+ */
+static inline int section_ext_useful(struct section_ext *section, struct psi_table_state *tstate)
+{
+ if ((section->version_number == tstate->version_number) && tstate->complete)
+ return 0;
+ if (section->version_number != tstate->version_number) {
+ if (section->section_number != 0)
+ return 0;
+
+ tstate->next_section_number = 0;
+ tstate->complete = 0;
+ tstate->version_number = section->version_number;
+ tstate->new_table = 1;
+ } else if (section->section_number == tstate->next_section_number) {
+ tstate->new_table = 0;
+ } else {
+ return 0;
+ }
+
+ tstate->next_section_number++;
+ if (section->last_section_number < tstate->next_section_number) {
+ tstate->complete = 1;
+ }
+
+ return 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/section_buf.c b/lib/libucsi/section_buf.c
new file mode 100644
index 0000000..35d465e
--- /dev/null
+++ b/lib/libucsi/section_buf.c
@@ -0,0 +1,173 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <errno.h>
+#include <string.h>
+#include "section_buf.h"
+
+#define SECTION_HDR_SIZE 3
+#define SECTION_PAD 0xff
+
+int section_buf_init(struct section_buf *section, int max)
+{
+ if (max < SECTION_HDR_SIZE)
+ return -EINVAL;
+
+ memset(section, 0, sizeof(struct section_buf));
+ section->max = max; /* max size of data */
+ section->len = SECTION_HDR_SIZE;
+ section->wait_pdu = 1;
+
+ return 0;
+}
+
+int section_buf_add(struct section_buf *section, uint8_t* frag, int len, int *section_status)
+{
+ int copy;
+ int used = 0;
+ uint8_t *data;
+ uint8_t *pos = (uint8_t*) section + sizeof(struct section_buf) + section->count;
+
+ /* have we finished? */
+ if (section->header && (section->len == section->count)) {
+ *section_status = 1;
+ return 0;
+ }
+
+ /* skip over section padding bytes */
+ *section_status = 0;
+ if (section->count == 0) {
+ while(len && (*frag == SECTION_PAD)) {
+ frag++;
+ len--;
+ used++;
+ }
+
+ if (len == 0)
+ return used;
+ }
+
+ /* grab the header to get the section length */
+ if (!section->header) {
+ /* copy the header frag */
+ copy = SECTION_HDR_SIZE - section->count;
+ if (copy > len)
+ copy = len;
+ memcpy(pos, frag, copy);
+ section->count += copy;
+ pos += copy;
+ frag += copy;
+ used += copy;
+ len -= copy;
+
+ /* we need 3 bytes for the section header */
+ if (section->count != SECTION_HDR_SIZE)
+ return used;
+
+ /* work out the length & check it isn't too big */
+ data = (uint8_t*) section + sizeof(struct section_buf);
+ section->len = SECTION_HDR_SIZE + (((data[1] & 0x0f) << 8) | data[2]);
+ if (section->len > section->max) {
+ *section_status = -ERANGE;
+ return len + used;
+ }
+
+ /* update fields */
+ section->header = 1;
+ }
+
+ /* accumulate frag */
+ copy = section->len - section->count;
+ if (copy > len)
+ copy = len;
+ memcpy(pos, frag, copy);
+ section->count += copy;
+ used += copy;
+
+ /* have we finished? */
+ if (section->header && (section->len == section->count))
+ *section_status = 1;
+
+ /* return number of bytes used */
+ return used;
+}
+
+int section_buf_add_transport_payload(struct section_buf *section,
+ uint8_t* payload, int len,
+ int pdu_start, int *section_status)
+{
+ int used = 0;
+ int tmp;
+
+ /* have we finished? */
+ if (section->header && (section->len == section->count)) {
+ *section_status = 1;
+ return 0;
+ }
+
+ /* don't bother if we're waiting for a PDU */
+ *section_status = 0;
+ if (section->wait_pdu && (!pdu_start))
+ return len;
+
+ /* if we're at a PDU start, we need extra handling for the extra first
+ * byte giving the offset to the start of the next section. */
+ if (pdu_start) {
+ /* we have received a pdu */
+ section->wait_pdu = 0;
+
+ /* work out the offset to the _next_ payload */
+ int offset = payload[0];
+ if ((offset+1) > len) {
+ section->wait_pdu = 1;
+ *section_status = -EINVAL;
+ return len;
+ }
+
+ /* accumulate the end if we need to */
+ if (section->count != 0) {
+ /* add the final fragment. */
+ tmp = section_buf_add(section, payload + 1, offset, section_status);
+
+ /* the stream said this was the final fragment
+ * (PDU START bit) - check that it really was! */
+ if ((tmp != offset) || section_buf_remaining(section) || (*section_status != 1)) {
+ *section_status = -ERANGE;
+ section->wait_pdu = 1;
+ return 1 + tmp;
+ }
+
+ /* it is complete - return the number of bytes we used */
+ return 1 + tmp;
+ }
+
+ /* otherwise, we skip the end of the previous section, and
+ * start accumulating the new data. */
+ used = 1 + offset;
+ }
+
+ /* ok, just accumulate the data as normal */
+ tmp = section_buf_add(section, payload+used, len - used, section_status);
+ if (*section_status < 0) {
+ section->wait_pdu = 1;
+ }
+
+ return used + tmp;
+}
diff --git a/lib/libucsi/section_buf.h b/lib/libucsi/section_buf.h
new file mode 100644
index 0000000..52d2f84
--- /dev/null
+++ b/lib/libucsi/section_buf.h
@@ -0,0 +1,124 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_SECTION_BUF_H
+#define _UCSI_SECTION_BUF_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+#define DVB_MAX_SECTION_BYTES 4096
+
+/**
+ * Buffer used to keep track of section fragments. You should allocate an
+ * area of memory of size (sizeof(section_buf) + <maxsectionsize>), and pass that area
+ * to section_buf_init() to set it up.
+ */
+struct section_buf {
+ uint32_t max; /* maximum size of section - setup by section_buf_init() */
+ uint32_t count; /* number of bytes currently accumulated */
+ uint32_t len; /* total number of bytes expected in the complete section */
+ uint8_t header:1; /* flag indicating the section header has been commpletely received */
+ uint8_t wait_pdu:1;/* flag indicating to wait till the next PDU start */
+ /* uint8_t data[] */
+};
+
+/**
+ * Initialise a section_buf structure.
+ *
+ * @param section The section_buf to initialise.
+ * @param max Maximum number of bytes in section (must be > 3)
+ * @return 0 on success, nonzero on error.
+ */
+extern int section_buf_init(struct section_buf *section, int max);
+
+/**
+ * Reset a section_buf structure (e.g. if a discontinuity occurred). The
+ * section_buf will wait for the first PDU start indicator.
+ *
+ * @param section The section_buf to reset.
+ */
+static inline void section_buf_reset(struct section_buf *section)
+{
+ int tmp = section->wait_pdu;
+ section_buf_init(section, section->max);
+ section->wait_pdu = tmp;
+}
+
+/**
+ * Add a data fragment to a section_buf.
+ *
+ * @param section section_buf to add to.
+ * @param frag Pointer to data fragment.
+ * @param len Number of bytes of data.
+ * @param section_status 0: nothing special. 1: section complete. -ERANGE indicates that the
+ * section is larger than section->max.
+ * @return Number of bytes which were consumed.
+ */
+extern int section_buf_add(struct section_buf *section, uint8_t* frag, int len, int *section_status);
+
+/**
+ * Add a transport packet PSI payload to a section_buf. This takes into account
+ * the extra byte present in PDU_START flagged packets.
+ *
+ * @param section section_buf to add to.
+ * @param payload Pointer to packet payload data.
+ * @param len Number of bytes of data.
+ * @param pdu_start True if the payload_unit_start_indicator flag was set in the
+ * TS packet.
+ * @param section_status 0: nothing special. 1: section complete. -ERANGE indicates that the
+ * section is larger than section->max. -EINVAL indicates the pointer_field was completely
+ * invalid (too large).
+ */
+extern int section_buf_add_transport_payload(struct section_buf *section,
+ uint8_t* payload, int len,
+ int pdu_start, int *section_status);
+
+/**
+ * Get the number of bytes left to be received in a section_buf.
+ *
+ * @param section The section_buf concerned.
+ * @return The number of bytes.
+ */
+static inline int section_buf_remaining(struct section_buf *section)
+{
+ return section->len - section->count;
+}
+
+/**
+ * Return a pointer to the start of the data in the section_buf.
+ *
+ * @param section The section_buf concerned.
+ * @return The data.
+ */
+static inline uint8_t* section_buf_data(struct section_buf *section)
+{
+ return (uint8_t*) section + sizeof(struct section_buf);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/testrecord.txt b/lib/libucsi/testrecord.txt
new file mode 100644
index 0000000..84d56aa
--- /dev/null
+++ b/lib/libucsi/testrecord.txt
@@ -0,0 +1,146 @@
+libucsi test record. Anything without PASS is either not tested, or is
+currently broken.
+
+Testing means (a) ensure there are no segfaults etc. (b) dump the raw hex,
+decode it by hand, and check it matches the output.
+
+Sections:
+PASS mpeg/cat_section.h
+ mpeg/odsmt_section.h
+PASS mpeg/pat_section.h
+PASS mpeg/pmt_section.h
+ mpeg/tsdt_section.h
+ mpeg/metadata_section.h
+
+PASS dvb/bat_section.h
+ dvb/dit_section.h
+PASS dvb/eit_section.h
+ dvb/int_section.h
+PASS dvb/nit_section.h
+ dvb/rst_section.h
+PASS dvb/sdt_section.h
+ dvb/sit_section.h
+PASS dvb/st_section.h
+PASS dvb/tdt_section.h
+PASS dvb/tot_section.h
+ dvb/tva_container_section.h
+
+PASS atsc/cvct_section.h
+ atsc/dccsct_section.h
+ atsc/dcct_section.h
+PASS atsc/eit_section.h
+PASS atsc/ett_section.h
+PASS atsc/mgt_section.h
+ atsc/rrt_section.h
+PASS atsc/stt_section.h
+PASS atsc/tvct_section.h
+
+Descriptors:
+PASS mpeg/audio_stream_descriptor.h
+PASS mpeg/ca_descriptor.h
+ mpeg/content_labelling_descriptor.h
+PASS mpeg/copyright_descriptor.h
+PASS mpeg/data_stream_alignment_descriptor.h
+PASS mpeg/external_es_id_descriptor.h
+ mpeg/fmc_descriptor.h
+PASS mpeg/fmxbuffer_size_descriptor.h
+ mpeg/hierarchy_descriptor.h
+ mpeg/ibp_descriptor.h
+ mpeg/iod_descriptor.h
+PASS mpeg/iso_639_language_descriptor.h
+PASS mpeg/maximum_bitrate_descriptor.h
+ mpeg/metadata_descriptor.h
+ mpeg/metadata_pointer_descriptor.h
+ mpeg/metadata_std_descriptor.h
+ mpeg/mpeg4_audio_descriptor.h
+ mpeg/mpeg4_video_descriptor.h
+ mpeg/multiplex_buffer_descriptor.h
+PASS mpeg/multiplex_buffer_utilization_descriptor.h
+ mpeg/muxcode_descriptor.h
+PASS mpeg/private_data_indicator_descriptor.h
+PASS mpeg/registration_descriptor.h
+ mpeg/sl_descriptor.h
+PASS mpeg/smoothing_buffer_descriptor.h
+PASS mpeg/std_descriptor.h
+PASS mpeg/system_clock_descriptor.h
+ mpeg/target_background_grid_descriptor.h
+PASS mpeg/video_stream_descriptor.h
+ mpeg/video_window_descriptor.h
+
+ dvb/ac3_descriptor.h
+ dvb/adaptation_field_data_descriptor.h
+ dvb/ait_application_descriptor.h
+ dvb/ait_application_icons_descriptor.h
+ dvb/ait_application_name_descriptor.h
+ dvb/ait_external_application_authorisation_descriptor.h
+ dvb/ancillary_data_descriptor.h
+ dvb/announcement_support_descriptor.h
+ dvb/application_signalling_descriptor.h
+PASS dvb/bouquet_name_descriptor.h
+PASS dvb/ca_identifier_descriptor.h
+ dvb/cable_delivery_descriptor.h
+ dvb/cell_frequency_link_descriptor.h
+ dvb/cell_list_descriptor.h
+PASS dvb/component_descriptor.h
+PASS dvb/content_descriptor.h
+ dvb/content_identifier_descriptor.h
+ dvb/country_availability_descriptor.h
+ dvb/data_broadcast_descriptor.h
+PASS dvb/data_broadcast_id_descriptor.h
+ dvb/default_authority_descriptor.h
+ dvb/dsng_descriptor.h
+ dvb/extended_event_descriptor.h
+PASS dvb/frequency_list_descriptor.h
+PASS dvb/linkage_descriptor.h
+PASS dvb/local_time_offset_descriptor.h
+ dvb/mhp_data_broadcast_id_descriptor.h
+ dvb/mosaic_descriptor.h
+ dvb/multilingual_bouquet_name_descriptor.h
+PASS dvb/multilingual_component_descriptor.h
+ dvb/multilingual_network_name_descriptor.h
+ dvb/multilingual_service_name_descriptor.h
+PASS dvb/network_name_descriptor.h
+ dvb/nvod_reference_descriptor.h
+PASS dvb/parental_rating_descriptor.h
+ dvb/partial_transport_stream_descriptor.h
+ dvb/pdc_descriptor.h
+PASS dvb/private_data_specifier_descriptor.h
+ dvb/related_content_descriptor.h
+ dvb/rnt_rar_over_dvb_stream_descriptor.h
+ dvb/rnt_rar_over_ip_descriptor.h
+ dvb/rnt_rnt_scan_descriptor.h
+ dvb/s2_satellite_delivery_descriptor.h
+PASS dvb/satellite_delivery_descriptor.h
+ dvb/scrambling_descriptor.h
+ dvb/service_availablility_descriptor.h
+PASS dvb/service_descriptor.h
+ dvb/service_identifier_descriptor.h
+PASS dvb/service_list_descriptor.h
+ dvb/service_move_descriptor.h
+PASS dvb/short_event_descriptor.h
+ dvb/short_smoothing_buffer_descriptor.h
+PASS dvb/stream_identifier_descriptor.h
+PASS dvb/stuffing_descriptor.h
+PASS dvb/subtitling_descriptor.h
+ dvb/telephone_descriptor.h
+ dvb/teletext_descriptor.h
+PASS dvb/terrestrial_delivery_descriptor.h
+ dvb/time_shifted_event_descriptor.h
+ dvb/time_shifted_service_descriptor.h
+ dvb/transport_stream_descriptor.h
+ dvb/tva_id_descriptor.h
+ dvb/vbi_data_descriptor.h
+ dvb/vbi_teletext_descriptor.h
+
+PASS atsc/ac3_descriptor.h
+PASS atsc/caption_service_descriptor.h
+ atsc/component_name_descriptor.h
+PASS atsc/content_advisory_descriptor.h
+ atsc/dcc_arriving_request_descriptor.h
+ atsc/dcc_departing_request_descriptor.h
+PASS atsc/extended_channel_name_descriptor.h
+ atsc/genre_descriptor.h
+ atsc/rc_descriptor.h
+PASS atsc/service_location_descriptor.h
+PASS atsc/stuffing_descriptor.h
+ atsc/time_shifted_service_descriptor.h
diff --git a/lib/libucsi/transport_packet.c b/lib/libucsi/transport_packet.c
new file mode 100644
index 0000000..ca6c2e1
--- /dev/null
+++ b/lib/libucsi/transport_packet.c
@@ -0,0 +1,256 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "transport_packet.h"
+
+#define CONTINUITY_VALID 0x80
+#define CONTINUITY_DUPESEEN 0x40
+
+int transport_packet_values_extract(struct transport_packet *pkt,
+ struct transport_values *out,
+ enum transport_value extract)
+{
+ uint8_t *end = (uint8_t*) pkt + TRANSPORT_PACKET_LENGTH;
+ uint8_t *adapend;
+ uint8_t *pos = (uint8_t*) pkt + sizeof(struct transport_packet);
+ enum transport_value extracted = 0;
+ enum transport_adaptation_flags adapflags = 0;
+ enum transport_adaptation_extension_flags adapextflags = 0;
+ int adaplength = 0;
+ int adapextlength = 0;
+
+ /* does the packet contain an adaptation field ? */
+ if ((pkt->adaptation_field_control & 2) == 0)
+ goto extract_payload;
+
+ /* get the adaptation field length and skip the byte */
+ adaplength = *pos++;
+
+ /* do we actually have any adaptation data? */
+ if (adaplength == 0)
+ goto extract_payload;
+
+ /* sanity check */
+ adapend = pos + adaplength;
+ if (adapend > end)
+ return -1;
+
+ /* extract the adaptation flags (we must have at least 1 byte to be here) */
+ adapflags = *pos++;
+
+ /* do we actually want anything else? */
+ if ((extract & 0xffff) == 0)
+ goto extract_payload;
+
+ /* PCR? */
+ if (adapflags & transport_adaptation_flag_pcr) {
+ if ((pos+6) > adapend)
+ return -1;
+
+ if (extract & transport_value_pcr) {
+ uint64_t base = ((uint64_t) pos[0] << 25) |
+ ((uint64_t) pos[1] << 17) |
+ ((uint64_t) pos[2] << 9) |
+ ((uint64_t) pos[3] << 1) |
+ ((uint64_t) pos[4] >> 7);
+ uint64_t ext = (((uint64_t) pos[4] & 1) << 8) |
+ (uint64_t) pos[5];
+ out->pcr= base * 300ULL + ext;
+ extracted |= transport_value_pcr;
+ }
+ pos += 6;
+ }
+
+ /* OPCR? */
+ if (adapflags & transport_adaptation_flag_opcr) {
+ if ((pos+6) > adapend)
+ return -1;
+
+ if (extract & transport_value_opcr) {
+ uint64_t base = ((uint64_t) pos[0] << 25) |
+ ((uint64_t) pos[1] << 17) |
+ ((uint64_t) pos[2] << 9) |
+ ((uint64_t) pos[3] << 1) |
+ ((uint64_t) pos[4] >> 7);
+ uint64_t ext = (((uint64_t) pos[4] & 1) << 8) |
+ (uint64_t) pos[5];
+ out->opcr= base * 300ULL + ext;
+ extracted |= transport_value_opcr;
+ }
+ pos += 6;
+ }
+
+ /* splice countdown? */
+ if (adapflags & transport_adaptation_flag_splicing_point) {
+ if ((pos+1) > adapend)
+ return -1;
+
+ if (extract & transport_value_splice_countdown) {
+ out->splice_countdown = *pos;
+ extracted |= transport_value_splice_countdown;
+ }
+ pos++;
+ }
+
+ /* private data? */
+ if (adapflags & transport_adaptation_flag_private_data) {
+ if ((pos+1) > adapend)
+ return -1;
+ if ((pos+1+*pos) > adapend)
+ return -1;
+
+ if (extract & transport_value_private_data) {
+ out->private_data_length = *pos;
+ out->private_data = pos + 1;
+ extracted |= transport_value_private_data;
+ }
+ pos += 1 + *pos;
+ }
+
+ /* is there an adaptation extension? */
+ if (!(adapflags & transport_adaptation_flag_extension))
+ goto extract_payload;
+
+ /* get/check the length */
+ if (pos >= adapend)
+ return -1;
+ adapextlength = *pos++;
+ if ((pos + adapextlength) > adapend)
+ return -1;
+
+ /* do we want/have anything in the adaptation extension? */
+ if (((extract & 0xff00) == 0) || (adapextlength == 0))
+ goto extract_payload;
+
+ /* extract the adaptation extension flags (we must have at least 1 byte
+ * to be here) */
+ adapextflags = *pos++;
+
+ /* LTW? */
+ if (adapextflags & transport_adaptation_extension_flag_ltw) {
+ if ((pos+2) > adapend)
+ return -1;
+
+ if (extract & transport_value_ltw) {
+ if (*pos & 0x80) {
+ out->ltw_offset = ((pos[0] & 0x7f) << 8) |
+ (pos[1]);
+ extracted |= transport_value_ltw;
+ }
+ }
+ pos += 2;
+ }
+
+ /* piecewise_rate? */
+ if (adapextflags & transport_adaptation_extension_flag_piecewise_rate) {
+ if ((pos+3) > adapend)
+ return -1;
+
+ if (extract & transport_value_piecewise_rate) {
+ out->piecewise_rate = ((pos[0] & 0x3f) << 16) |
+ (pos[1] << 8) |
+ pos[2];
+ extracted |= transport_value_piecewise_rate;
+ }
+ pos += 3;
+ }
+
+ /* seamless_splice? */
+ if (adapextflags & transport_adaptation_extension_flag_seamless_splice) {
+ if ((pos+5) > adapend)
+ return -1;
+
+ if (extract & transport_value_piecewise_rate) {
+ out->splice_type = pos[0] >> 4;
+ out->dts_next_au = ((pos[0] & 0x0e) << 29) |
+ (pos[1] << 22) |
+ ((pos[2] & 0xfe) << 14) |
+ (pos[3] << 7) |
+ ((pos[4] & 0xfe) >> 1);
+ extracted |= transport_value_seamless_splice;
+ }
+ pos += 5;
+ }
+
+
+
+extract_payload:
+ /* does the packet contain a payload? */
+ if (pkt->adaptation_field_control & 1) {
+ int off = sizeof(struct transport_packet);
+ if (pkt->adaptation_field_control & 2)
+ off++;
+ off += adaplength;
+
+ out->payload = (uint8_t*) pkt + off;
+ out->payload_length = TRANSPORT_PACKET_LENGTH - off;
+ } else {
+ out->payload = NULL;
+ out->payload_length = 0;
+ }
+
+ out->flags = adapflags;
+ return extracted;
+}
+
+int transport_packet_continuity_check(struct transport_packet *pkt,
+ int discontinuity_indicator, unsigned char *cstate)
+{
+ unsigned char pktcontinuity = pkt->continuity_counter;
+ unsigned char prevcontinuity = *cstate & 0x0f;
+ unsigned char nextcontinuity;
+
+ /* NULL packets have undefined continuity */
+ if (transport_packet_pid(pkt) == TRANSPORT_NULL_PID)
+ return 0;
+
+ /* is the state valid? */
+ if (!(*cstate & CONTINUITY_VALID)) {
+ *cstate = pktcontinuity | CONTINUITY_VALID;
+ return 0;
+ }
+
+ /* check for discontinuity_indicator */
+ if (discontinuity_indicator) {
+ *cstate = pktcontinuity | CONTINUITY_VALID;
+ return 0;
+ }
+
+ /* only packets with a payload should increment the counter */
+ if (pkt->adaptation_field_control & 1)
+ nextcontinuity = (prevcontinuity + 1) & 0xf;
+ else
+ nextcontinuity = prevcontinuity;
+
+ /* check for a normal continuity progression */
+ if (nextcontinuity == pktcontinuity) {
+ *cstate = pktcontinuity | CONTINUITY_VALID;
+ return 0;
+ }
+
+ /* one dupe is allowed */
+ if ((prevcontinuity == pktcontinuity) && (!(*cstate & CONTINUITY_DUPESEEN))) {
+ *cstate = pktcontinuity | (CONTINUITY_VALID|CONTINUITY_DUPESEEN);
+ return 0;
+ }
+
+ /* continuity error */
+ return -1;
+}
diff --git a/lib/libucsi/transport_packet.h b/lib/libucsi/transport_packet.h
new file mode 100644
index 0000000..6314eca
--- /dev/null
+++ b/lib/libucsi/transport_packet.h
@@ -0,0 +1,195 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_TRANSPORT_PACKET_H
+#define _UCSI_TRANSPORT_PACKET_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+#include "descriptor.h"
+
+#define TRANSPORT_PACKET_LENGTH 188
+#define TRANSPORT_PACKET_SYNC 0x47
+#define TRANSPORT_MAX_PIDS 0x2000
+#define TRANSPORT_NULL_PID 0x1fff
+
+
+/**
+ * Enumeration of adaptation field control values.
+ */
+enum transport_adaptation_field_control {
+ transport_adaptation_field_control_reserved = 0x00,
+ transport_adaptation_field_control_payload_only = 0x01,
+ transport_adaptation_field_control_adaptation_only = 0x02,
+ transport_adaptation_field_control_adaptation_payload = 0x03,
+};
+
+/**
+ * Enumeration of scrambling control values.
+ */
+enum transport_scrambling_control {
+ transport_scrambling_control_unscrambled = 0x00,
+ transport_scrambling_control_user_1 = 0x01,
+ transport_scrambling_control_user_2 = 0x02,
+ transport_scrambling_control_user_3 = 0x03,
+};
+
+/**
+ * Enumeration of adaptation flags.
+ */
+enum transport_adaptation_flags {
+ transport_adaptation_flag_discontinuity = 0x80,
+ transport_adaptation_flag_random_access = 0x40,
+ transport_adaptation_flag_es_priority = 0x20,
+ transport_adaptation_flag_pcr = 0x10,
+ transport_adaptation_flag_opcr = 0x08,
+ transport_adaptation_flag_splicing_point = 0x04,
+ transport_adaptation_flag_private_data = 0x02,
+ transport_adaptation_flag_extension = 0x01,
+};
+
+/**
+ * Enumeration of adaptation extension flags.
+ */
+enum transport_adaptation_extension_flags {
+ transport_adaptation_extension_flag_ltw = 0x80,
+ transport_adaptation_extension_flag_piecewise_rate = 0x40,
+ transport_adaptation_extension_flag_seamless_splice = 0x20,
+};
+
+/**
+ * Enumeration of flags controlling which values to extract using the
+ * transport_packet_values_extract() function.
+ */
+enum transport_value {
+ /* normal adaptation */
+ transport_value_pcr = 0x0001,
+ transport_value_opcr = 0x0002,
+ transport_value_splice_countdown = 0x0004,
+ transport_value_private_data = 0x0008,
+
+ /* extension adaptation */
+ transport_value_ltw = 0x0100,
+ transport_value_piecewise_rate = 0x0200,
+ transport_value_seamless_splice = 0x0400,
+};
+
+/**
+ * Structure describing a transport packet header.
+ */
+struct transport_packet {
+ uint8_t sync_byte;
+ EBIT4(uint8_t transport_error_indicator : 1; ,
+ uint8_t payload_unit_start_indicator : 1; ,
+ uint8_t transport_priority : 1; ,
+ uint8_t pid_hi : 5; );
+ uint8_t pid_lo;
+ EBIT3(uint8_t transport_scrambling_control : 2; ,
+ uint8_t adaptation_field_control : 2; ,
+ uint8_t continuity_counter : 4; );
+ /* values */
+} __ucsi_packed;
+
+/**
+ * Structure to extract values into using the transport_packet_values_extract()
+ * function.
+ */
+struct transport_values {
+ enum transport_adaptation_flags flags; /* always extracted */
+ uint8_t *payload; /* always extracted */
+ uint16_t payload_length; /* always extracted */
+
+ uint64_t pcr;
+ uint64_t opcr;
+ uint8_t splice_countdown;
+ uint8_t private_data_length;
+ uint8_t *private_data;
+ uint16_t ltw_offset;
+ uint32_t piecewise_rate;
+ uint8_t splice_type;
+ uint64_t dts_next_au;
+};
+
+/**
+ * Extract the PID from a transport packet.
+ *
+ * @param pkt The packet.
+ * @return The PID.
+ */
+static inline int transport_packet_pid(struct transport_packet *pkt)
+{
+ return (pkt->pid_hi << 8) | (pkt->pid_lo);
+}
+
+/**
+ * Process a buffer into a transport packet.
+ *
+ * @param buf Raw buffer. Note, this function assumes there are 188 bytes available.
+ * @return transport_packet pointer, or NULL on error.
+ */
+static inline struct transport_packet *transport_packet_init(unsigned char *buf)
+{
+ struct transport_packet *pkt = (struct transport_packet*) buf;
+
+ if (pkt->sync_byte != TRANSPORT_PACKET_SYNC)
+ return NULL;
+
+ if (transport_packet_pid(pkt) >= TRANSPORT_MAX_PIDS)
+ return NULL;
+
+ return pkt;
+}
+
+/**
+ * Check the continuity counter for a packet in a PID stream.
+ *
+ * @param pkt transport_packet to check.
+ * @param discontinuity_indicator Set to 1 if the packet's discontinuity_indicator flag is set.
+ * @param cstate Pointer to a single 8 bit character, used to store state for validating
+ * continuity. To initialise the state, simply set it to 0 before the first call.
+ * @return 0 if the continuity was correct, or nonzero on error. cstate will not be updated on error,
+ * it is up to the caller to clear it to accept the next packet.
+ */
+extern int transport_packet_continuity_check(struct transport_packet *pkt,
+ int discontinuity_indicator, unsigned char *cstate);
+
+/**
+ * Extract selected fields from a transport packet.
+ *
+ * @param pkt The packet.
+ * @param out Destination structure for values.
+ * @param extract Orred bitmask of enum transport_value - tells it what fields
+ * to extract if they are available.
+ * @return < 0 => error. Otherwise, an orred bitmask of enum transport_value
+ * telling you what fields were successfully extracted.
+ */
+extern int transport_packet_values_extract(struct transport_packet *pkt,
+ struct transport_values *out,
+ enum transport_value extract);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/libucsi/types.h b/lib/libucsi/types.h
new file mode 100644
index 0000000..b01d79a
--- /dev/null
+++ b/lib/libucsi/types.h
@@ -0,0 +1,36 @@
+/*
+ * section and descriptor parser
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _UCSI_TYPES_H
+#define _UCSI_TYPES_H 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef uint8_t iso639lang_t[3];
+typedef uint8_t iso639country_t[3];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libdvb2/README b/libdvb2/README
deleted file mode 100644
index 049acd6..0000000
--- a/libdvb2/README
+++ /dev/null
@@ -1,23 +0,0 @@
-Late in 2003 the idea to create a simple DVB library from the code snippets
-in the test/utility programs was discussed on the linux-dvb mailing list.
-Hopefully someone will invest some time in this project to turn the idea into
-reality...
-
-Here is an outline of what libdvb2 should be, according to my recollection:
-(For first hand information search the linux-dvb list archives for "libdvb2".)
-
-- C
-- small: The goal is to make the library usable in *any* DVB project, which
- is easier if the library sticks to the basics. Advanced stuff can be
- done in a second library. What exacty "basic" and "advanced" means
- is subject of discussion, but I want avoid to impose a certain programming
- model (e.g. multi-threaded vw. event-loop) on users of the library.
-- a prime target is to establish a standard DVB config and service list
- format, to make this sharable between different applications
-- LGPL
-
-About the name: There already is a libdvb written by the Metzler Bros.,
-but the main drawback is that it is written in C++ and thus rejected
-by many projects.
-
-Johannes Stezenbach <js@convergence.de>
diff --git a/test/Makefile b/test/Makefile
index ddff9ab..30cb9e3 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,37 +1,41 @@
-# Makefile for Linux DVB API Version 3 test programs
+# Makefile for linuxtv.org dvb-apps/test
-CC = gcc
-CFLAGS = -g -O2 -W -Wall -I../include
+objects = hex_dump.o lnb.o
-TARGETS = \
- diseqc \
- set22k \
- sendburst \
- setvoltage \
- setpid \
- video \
- test_sections \
- test_sec_ne \
- test_pes \
- test_dvr \
- test_dvr_play \
- test_tt \
- test_av \
- test_av_play \
- test_vevent \
- test_stc \
- test_stillimage
+binaries = diseqc \
+ sendburst \
+ set22k \
+ setpid \
+ setvoltage \
+ test_av \
+ test_av_play \
+ test_dvr \
+ test_dvr_play \
+ test_pes \
+ test_sec_ne \
+ test_sections \
+ test_stc \
+ test_stillimage \
+ test_tt \
+ test_vevent \
+ evtest \
+ video \
+ szap2
-# test \
-# test_audio \
-# test_front \
-# test_switch \
-# test_video \
+.PHONY: all
-all: $(TARGETS)
+all: $(binaries)
+ make -C libdvbcfg $@
+ make -C libdvben50221 $@
+ make -C libesg $@
+ make -C libucsi $@
-test_sections test_sec_ne test_pes test_tt: hex_dump.o
+$(binaries): $(objects)
-clean:
- rm -f $(TARGETS) *.o
+clean::
+ make -C libdvbcfg $@
+ make -C libdvben50221 $@
+ make -C libesg $@
+ make -C libucsi $@
+include ../Make.rules
diff --git a/test/README b/test/README
index b3f0cac..2b39936 100644
--- a/test/README
+++ b/test/README
@@ -1,4 +1,4 @@
-Various small test/sample programs for the Linux DVB API Version 2
+Various small test/sample programs for the Linux DVB API Version 2/3
The default devices used by the test programs are generally
/dev/dvb/adapter0/*0, and can be overridden using environment
@@ -33,13 +33,13 @@ test_vevent : Test VIDEO_GET_EVENT and poll() for video events
test_stc : Test DMX_GET_STC.
test_stillimage : Display single iframes as stillimages
- iframes can be created with the 'convert' tool from
- imagemagick and mpeg2encode from ftp.mpeg.org, and must
+ iframes can be created with the 'convert' tool from
+ imagemagick and mpeg2encode from ftp.mpeg.org, and must
have a supported size, e.g. 702x576
($ convert -sample 702x576\! test.jpg test.mpg)
-(test_av_play : Test playing MPEG TS from a file (apparently broken))
-
+test_av_play : Test playing MPEG PES (VDR format) from a file
+test_dvr_play : Test playing MPEG TS from a file (don't try, driver is broken)
test :
test_audio :
@@ -48,4 +48,3 @@ test_dvr :
test_front :
test_switch :
test_video :
-
diff --git a/test/dia b/test/dia
index 5cb2600..d737432 100755..100644
--- a/test/dia
+++ b/test/dia
@@ -4,4 +4,4 @@ for f in $@
do /usr/X11R6/bin/convert -geomtry 702x576 $f test.mpg
test_video test.mpg
rm test.mpg
-done \ No newline at end of file
+done
diff --git a/test/diseqc.c b/test/diseqc.c
index 8f2e411..5deb7fe 100644
--- a/test/diseqc.c
+++ b/test/diseqc.c
@@ -1,11 +1,13 @@
-/*
- * Test sending DiSEqC commands on a SAT frontend.
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX diseqc [test_seq_no]
- */
+#define USAGE \
+"\n" \
+"\nTest sending DiSEqC commands on a SAT frontend." \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX diseqc [test_seq_no|'all']" \
+"\n"
#include <pthread.h>
#include <time.h>
+#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
@@ -109,7 +111,10 @@ int main(int argc, char **argv)
return -1;
}
- if (argc > 1) {
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s [number|'all']\n" USAGE, argv[0]);
+ return 1;
+ } else if (strcmp(argv[1], "all")) {
int i = atol(argv[1]);
cmd[0] = &switch_cmds[i];
diseqc_send_msg(fd,
@@ -136,5 +141,3 @@ int main(int argc, char **argv)
return 0;
}
-
-
diff --git a/test/evtest.c b/test/evtest.c
new file mode 100644
index 0000000..a61593e
--- /dev/null
+++ b/test/evtest.c
@@ -0,0 +1,251 @@
+/*
+ * $Id: evtest.c,v 1.3 2005/08/15 20:43:52 js Exp $
+ *
+ * Copyright (c) 1999-2000 Vojtech Pavlik
+ *
+ * Event device test program
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+
+#include <linux/input.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *events[EV_MAX + 1] = { "Sync", "Key", "Relative", "Absolute", "Misc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, "LED", "Sound", NULL, "Repeat", "ForceFeedback", "Power", "ForceFeedbackStatus"};
+char *syncs[2] = { "Sync", "Config"};
+char *keys[KEY_MAX + 1] = {
+ // 0x000
+ "Reserved", "Esc", "1", "2", "3", "4", "5", "6",
+ "7", "8", "9", "0", "Minus", "Equal", "Backspace", "Tab",
+ // 0x010
+ "Q", "W", "E", "R", "T", "Y", "U", "I",
+ "O", "P", "LeftBrace", "RightBrace", "Enter", "LeftControl", "A", "S",
+ // 0x020
+ "D", "F", "G", "H", "J", "K", "L", "Semicolon",
+ "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z", "X", "C", "V",
+ // 0x030
+ "B", "N", "M", "Comma", "Dot", "Slash", "RightShift", "KPAsterisk",
+ "LeftAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5",
+ // 0x040
+ "F6", "F7", "F8", "F9", "F10", "NumLock", "ScrollLock", "KP7",
+ "KP8", "KP9", "KPMinus", "KP4", "KP5", "KP6", "KPPlus", "KP1",
+ // 0x050
+ "KP2", "KP3", "KP0", "KPDot", NULL, "ZENKAKUHANKAKU", "102nd", "F11",
+ "F12", "RO", "KATAKANA", "HIRAGANA", "HENKAN", "KATAKANAHIRAGANA", "MUHENKAN", "KPJPCOMMA",
+ // 0x060
+ "KPEnter", "RightCtrl", "KPSlash", "SysRq", "RightAlt", "LineFeed", "Home", "Up",
+ "PageUp", "Left", "Right", "End", "Down", "PageDown", "Insert", "Delete",
+ // 0x070
+ "Macro", "Mute", "VolumeDown", "VolumeUp", "Power", "KPEqual", "KPPlusMinus", "Pause",
+ NULL, "KPComma", "HANGUEL", "HANJA", "YEN", "LeftMeta", "RightMeta", "Compose",
+ // 0x080
+ "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open", "Paste",
+ "Find", "Cut", "Help", "Menu", "Calc", "Setup", "Sleep", "WakeUp",
+ // 0x090
+ "File", "SendFile", "DeleteFile", "X-fer", "Prog1", "Prog2", "WWW", "MSDOS",
+ "Coffee", "Direction", "CycleWindows", "Mail", "Bookmarks", "Computer", "Back", "Forward",
+ // 0x0A0
+ "CloseCD", "EjectCD", "EjectCloseCD", "NextSong", "PlayPause", "PreviousSong", "StopCD", "Record",
+ "Rewind", "Phone", "ISOKey", "Config", "HomePage", "Refresh", "Exit", "Move",
+ // 0x0B0
+ "Edit", "ScrollUp", "ScrollDown", "KPLeftParenthesis", "KPRightParenthesis", NULL, NULL, "F13",
+ "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21",
+ // 0x0C0
+ "F22", "F23", "F24", NULL, NULL, NULL, NULL, NULL,
+ "PlayCD", "PauseCD", "Prog3", "Prog4", NULL, "Suspend", "Close", "Play",
+ // 0x0D0
+ "FastForward", "BassBoost", "Print", "HP", "Camera", "Sound", "Question", "EMail",
+ "Chat", "Search", "Connect", "Finance", "Sport", "Shop", "AltErase", "Cancel",
+ // 0x0E0
+ "BrightnessDown", "BrightnessUp", "Media", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x0F0
+ "Unknown", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x100
+ "Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7",
+ "Btn8", "Btn9", NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x110
+ "LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn", "TaskBtn",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x120
+ "Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn", "BaseBtn", "BaseBtn2",
+ "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6", NULL, NULL, NULL, "BtnDead",
+ // 0x130
+ "BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR",
+ "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode", "BtnThumbL", "BtnThumbR", NULL,
+ // 0x140
+ "ToolPen", "ToolRubber", "ToolBrush", "ToolPencil", "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens",
+ NULL, NULL, "Touch", "Stylus", "Stylus2", "ToolDoubleTap", "ToolTripleTap", NULL,
+ // 0x150
+ "GearDown", "GearUp", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x160
+ "Ok", "Select", "Goto", "Clear", "Power2", "Option", "Info", "Time",
+ "Vendor", "Archive", "Program", "Channel", "Favorites", "EPG", "PVR", "MHP",
+ // 0x170
+ "Language", "Title", "Subtitle", "Angle", "Zoom", "Mode", "Keyboard", "Screen",
+ "PC", "TV", "TV2", "VCR", "VCR2", "Sat", "Sat2", "CD",
+ // 0x180
+ "Tape", "Radio", "Tuner", "Player", "Text", "DVD", "Aux", "MP3",
+ "Audio", "Video", "Directory", "List", "Memo", "Calendar", "Red", "Green",
+ // 0x190
+ "Yellow", "Blue", "ChannelUp", "ChannelDown", "First", "Last", "AB", "Next",
+ "Restart", "Slow", "Shuffle", "Break", "Previous", "Digits", "Teen", "Twen",
+ // 0x1A0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1B0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1C0
+ "DelEOL", "DelEOS", "InsLine", "DelLine", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1D0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1E0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1F0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };
+char *relatives[REL_MAX + 1] = {
+ "X", "Y", "Z", NULL, NULL, NULL, "HWheel", "Dial",
+ "Wheel", "Misc", NULL, NULL, NULL, NULL, NULL, NULL,
+};
+char *absolutes[ABS_MAX + 1] = {
+ // 0x00
+ "X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder",
+ "Wheel", "Gas", "Brake", NULL, NULL, NULL, NULL, NULL,
+ // 0x10
+ "Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat 3Y",
+ "Pressure", "Distance", "XTilt", "YTilt", "ToolWidth", NULL, NULL, NULL,
+ // 0x20
+ "Volume", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "Misc", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x30
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+char *leds[LED_MAX + 1] = { "NumLock", "CapsLock", "ScrollLock", "Compose", "Kana", "Sleep", "Suspend", "Mute" };
+char *repeats[REP_MAX + 1] = { "Delay", "Period" };
+char *sounds[SND_MAX + 1] = { "Bell", "Click" };
+
+char **names[EV_MAX + 1] = { syncs, keys, relatives, absolutes, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+NULL, NULL, leds, sounds, NULL, repeats, NULL, NULL, NULL };
+
+#ifndef BITS_PER_LONG
+#define BITS_PER_LONG (sizeof(long) * 8)
+#endif
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define BIT(x) (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+int main (int argc, char **argv)
+{
+ int fd, rd, i, j, k;
+ struct input_event ev[64];
+ int version;
+ unsigned short id[4];
+ unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+ char name[256] = "Unknown";
+ int _abs[5];
+
+ if (argc < 2) {
+ printf("Usage: evtest /dev/input/eventX\n");
+ printf("Where X = input device number\n");
+ exit(1);
+ }
+
+ if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
+ perror("evtest");
+ exit(1);
+ }
+
+ if (ioctl(fd, EVIOCGVERSION, &version)) {
+ perror("evtest: can't get version");
+ exit(1);
+ }
+
+ printf("Input driver version is %d.%d.%d\n",
+ version >> 16, (version >> 8) & 0xff, version & 0xff);
+
+ ioctl(fd, EVIOCGID, id);
+ printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
+ id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
+
+ ioctl(fd, EVIOCGNAME(sizeof(name)), name);
+ printf("Input device name: \"%s\"\n", name);
+
+ memset(bit, 0, sizeof(bit));
+ ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+ printf("Supported events:\n");
+
+ for (i = 0; i < EV_MAX; i++)
+ if (test_bit(i, bit[0])) {
+ printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
+ ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
+ for (j = 0; j < KEY_MAX; j++)
+ if (test_bit(j, bit[i])) {
+ printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
+ if (i == EV_ABS) {
+ ioctl(fd, EVIOCGABS(j), _abs);
+ for (k = 0; k < 5; k++)
+ if ((k < 3) || _abs[k])
+ printf(" %s %6d\n", absval[k], _abs[k]);
+ }
+ }
+ }
+
+
+ printf("Testing ... (interrupt to exit)\n");
+
+ while (1) {
+ rd = read(fd, ev, sizeof(struct input_event) * 64);
+
+ if (rd < (int) sizeof(struct input_event)) {
+ printf("yyy\n");
+ perror("\nevtest: error reading");
+ exit (1);
+ }
+
+ for (i = 0; i < rd / (int) sizeof(struct input_event); i++)
+ printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
+ ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
+ events[ev[i].type] ? events[ev[i].type] : "?",
+ ev[i].code,
+ names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
+ ev[i].value);
+
+ }
+}
diff --git a/test/hex_dump.c b/test/hex_dump.c
index c7c8ede..b5c08cb 100644
--- a/test/hex_dump.c
+++ b/test/hex_dump.c
@@ -60,4 +60,3 @@ void hex_dump(uint8_t data[], int bytes)
}
printf("\n");
}
-
diff --git a/test/libdvbcfg/Makefile b/test/libdvbcfg/Makefile
new file mode 100644
index 0000000..7705f9b
--- /dev/null
+++ b/test/libdvbcfg/Makefile
@@ -0,0 +1,12 @@
+# Makefile for linuxtv.org dvb-apps/test/libdvbcfg
+
+binaries = dvbcfg_test
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbcfg/libdvbcfg.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libdvbcfg/dvbcfg_test.c b/test/libdvbcfg/dvbcfg_test.c
new file mode 100644
index 0000000..de10e43
--- /dev/null
+++ b/test/libdvbcfg/dvbcfg_test.c
@@ -0,0 +1,100 @@
+/**
+ * dvbcfg testing.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+
+void syntax(void);
+
+struct dvbcfg_zapchannel *channels = NULL;
+int zapcount = 0;
+int zappos = 0;
+
+int zapload_callback(struct dvbcfg_zapchannel *channel, void *private);
+int zapsave_callback(struct dvbcfg_zapchannel *channel, void *private);
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4) {
+ syntax();
+ }
+
+ if (!strcmp(argv[1], "-zapchannel")) {
+
+ FILE *f = fopen(argv[2], "r");
+ if (!f) {
+ fprintf(stderr, "Unable to load %s\n", argv[2]);
+ exit(1);
+ }
+ dvbcfg_zapchannel_parse(f, zapload_callback, NULL);
+ fclose(f);
+
+ f = fopen(argv[3], "w");
+ if (!f) {
+ fprintf(stderr, "Unable to write %s\n", argv[3]);
+ exit(1);
+ }
+ dvbcfg_zapchannel_save(f, zapsave_callback, NULL);
+ fclose(f);
+
+ } else {
+ syntax();
+ }
+
+ exit(0);
+}
+
+int zapload_callback(struct dvbcfg_zapchannel *channel, void *private)
+{
+ (void) private;
+
+ struct dvbcfg_zapchannel *tmp = realloc(channels, (zapcount+1) * sizeof(struct dvbcfg_zapchannel));
+ if (tmp == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ channels = tmp;
+
+ memcpy(&channels[zapcount++], channel, sizeof(struct dvbcfg_zapchannel));
+
+ return 0;
+}
+
+int zapsave_callback(struct dvbcfg_zapchannel *channel, void *private)
+{
+ (void) private;
+
+ if (zappos >= zapcount)
+ return 1;
+
+ memcpy(channel, channels + zappos, sizeof(struct dvbcfg_zapchannel));
+ zappos++;
+
+ return 0;
+}
+
+void syntax()
+{
+ fprintf(stderr,
+ "Syntax: dvbcfg_test <-zapchannel> <input filename> <output filename>\n");
+ exit(1);
+}
diff --git a/test/libdvbcfg/test_zapchannels.txt b/test/libdvbcfg/test_zapchannels.txt
new file mode 100644
index 0000000..98a5b41
--- /dev/null
+++ b/test/libdvbcfg/test_zapchannels.txt
@@ -0,0 +1,446 @@
+# Most of the major channels in the Raleigh Durham Area. Frequencies the NTSC center freq.
+WRAL:707000000:8VSB:33:36
+WNCN:719000000:8VSB:49:52
+WTVD:701000000:8VSB:49:52
+WRAZ:683000000:8VSB:49:52
+WUNC:743000000:8VSB:49:52
+WRDU:551000000:8VSB:33:36
+WLFL:731000000:8VSB:33:36
+3sat:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:210:220
+ARD-Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1805
+CNBC:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:510:520
+DLF-Köln:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:810
+DLR-Berlin:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:710
+EinsExtra:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102
+EinsFestival:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202
+EinsMuXx:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:301:302
+EuroNews:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2221:2233
+Eurosport:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:410:420
+Fritz:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:901
+KiKa:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:310:320
+MDR FERNSEHEN:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:401:402
+MDR KULTUR:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:801
+MDR info:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1101
+MHP ARD Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:102
+NDR Fernsehen:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2401:2402
+ORB-Fernsehen:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:501:502
+RADIOmultikulti:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1301
+Radio 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:701
+SFB1:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602
+SWR2:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1401
+SÃœDWEST BW:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:801:802
+SÃœDWEST RP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3101:3102
+WDR 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1501
+WDR 5:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1601
+ZDF:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:110:120
+ZDFdigitext:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+ZDFdokukanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:660:670
+ZDFinfokanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:610:620
+ZDFtheaterkanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+JUMP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1001
+SPUTNIK:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1201
+Österreich 1:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:169
+ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632
+ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632
+Adagio:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+All Jazz:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Avante:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:741:743
+B5 aktuell:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3101
+BBC Prime:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:761:762
+BData3:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+BData4:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+BData5:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+BR-alpha:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702
+Barock Fantasie:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Bayerisches FS:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202
+Bayern 1:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3601
+Bayern 4 Klassik:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3001
+BibelTV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:731:732
+Bloomberg:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+CLASSICA:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:767:768
+COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:656
+Canal 24 Horas:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:991:992
+Club:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:711:713
+Cristal New Age:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+DANCE:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:304
+DW-tv:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:634:632
+Das Erste:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102
+Detskij Mir:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:931:932
+ERT-Sat:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:691:692
+Einstein TV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702
+Euronews:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:597:596
+Eurosport News:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:771:772
+Extreme Sports:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:791:793
+Extreme Sports:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Fashion TV:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Fox Kids:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:671:672
+Fox Kids:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:671:673
+GOLD:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:320
+HITLISTE:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:784
+HR XXL:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3501
+JAZZ:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:640
+Jazz legends:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Kabel Wizard:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Kanal 7:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Kanal 7:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:49:52
+Kanal D:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:651:652
+Kanal D:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:651:652
+LATIN:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:368
+Landscape:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Leitseite:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2254:0
+Liberty TV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:721:723
+MTV Base:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:781:782
+MV-Test:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Modem-Setup:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Movie Sounds:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Musica Antica:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Musica Camerata:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+NDR Info:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3701
+NTV international:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+NTVI:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:611:612
+Nashe Kino:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:621:622
+NordwestRadio:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3801
+OLD GOLD:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:336
+Opernfestival:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PCNE:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:681:682
+PREMIERE SPORT INTERACTIVE:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 1:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 2:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 3:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 4:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2815:2816
+PREMIERE EROTIK:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280
+PREMIERE NOSTALGIE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2559:2560
+PREMIERE SERIE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024
+PREMIERE SPORT 1:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:258
+PREMIERE SPORT 2:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3839:3840
+PREMIERE START:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256
+Parlamentsfernsehen:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:33:36
+Phoenix:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:901:902
+Portal:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+RTP Internacional:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:661:662
+Rai 1:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:951:952
+Rai 2:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:961:962
+Rai 3:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:971:972
+SCHLAGER:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384
+SR 1:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3901
+SR Fernsehen Suedwest:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:501:502
+Show TV:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:911:912
+Sinfonica:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+TGRT:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:921:922
+TM V1.0:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+TV Polonia:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:641:642
+TVEi:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:981:982
+TW1:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:751:752
+Test-R:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702
+Travel:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:595:594
+VCR-Setup:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+VH1 Classic:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:604:603
+Videotext:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+WDR FERNSEHEN:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602
+ZEE TV:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+arte:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:401:403
+hessen fernsehen:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:301:302
+hr-chronos:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3201
+hr-klassik:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3401
+hr2:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3301
+13 TH STREET:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2303:2304
+ALTERNATIVE ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:544
+BEATE-UHSE.TV:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024
+CHILLOUT:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:400
+CLASSIC ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:352
+DISCOVERY CHANNEL:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1792
+DISNEY CHANNEL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2559:2560
+DEUTSCHE HITS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:800
+EASY LISTENING:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:608
+Einstein:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+FILM & MUSICAL:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592
+FOX KIDS:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280
+GOLDSTAR TV:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3839:3840
+HARD ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:816
+HEIMATKANAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
+HIP HOP/R&B:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:576
+JUNIOR:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256
+K-TOON:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+KLASSIK POPULÄR:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:624
+KRIMI &CO:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
+LOVE SONGS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592
+NEW COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384
+ORCHESTRALE WERKE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:560
+PLANET:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1792
+PREMIERE 1:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:511:512
+PREMIERE 2:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1793
+PREMIERE 3:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2303:2304
+PREMIERE 4:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:767:768
+PREMIERE 5:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280
+PREMIERE 6:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
+PREMIERE 7:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024
+SOUL CLASSICS:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:352
+STUDIO UNIVERSAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2047:2048
+Sonnenklar TV:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Das Erste:11837:h:0:27500:101:102:28106
+ZDF:11954:h:0:27500:110:120:28006
+3sat:11954:h:0:27500:210:220:28007
+EinsMuXx:12110:h:0:27500:301:302:28203
+EinsFestival:12110:h:0:27500:201:202:28202
+EinsExtra:12110:h:0:27500:101:102:28201
+MDR FERNSEHEN:12110:h:0:27500:401:402:28204
+ORB-Fernsehen:12110:h:0:27500:501:502:28205
+B1 Berlin:12110:h:0:27500:601:602:28206
+SWR Fernsehen:11837:h:0:27500:801:802:28113
+SR Fernsehen Suedwes:11837:h:0:27500:501:502:28110
+hessen fernsehen:11837:h:0:27500:301:302:28108
+WDR FERNSEHEN:11837:h:0:27500:601:602:28111
+Bayerisches FS:11837:h:0:27500:201:202:28107
+N3:12110:h:0:27500:2401:2402:28224
+BR-alpha:11837:h:0:27500:701:702:28112
+KiKa:11954:h:0:27500:310:320:28008
+arte:11836:h:0:27500:401:402:28109
+ZDF Theaterkanal:11954:h:0:27500:1110:1120:28016
+ZDF.info:11954:h:0:27500:610:620:28011
+ZDF.doku:11954:h:0:27500:660:670:28014
+Phoenix:11837:h:0:27500:901:902:28114
+DW-tv:10786:v:0:21997:305:306:9005
+RTL Television:12188:h:0:27500:163:104:12003
+SAT.1:12480:v:0:27500:1791:1792:46
+ProSieben:12480:v:0:27500:255:256:898
+RTL2:12188:h:0:27500:166:128:12020
+Super RTL:12188:h:0:27500:165:120:12040
+KABEL1:12480:v:0:27500:511:512:899
+VOX:12188:h:0:27500:167:136:12060
+tm3:12480:v:0:27500:767:768:897
+Bloomberg TV Germany:12552:v:0:22000:162:99:12160
+EuroNews:11954:h:0:27500:2221:2233:28015
+N24:12480:v:0:27500:2047:2048:47
+n-tv:12670:v:0:22000:162:96:12730
+DSF:12480:v:0:27500:1023:1024:900
+Eurosport:11954:h:0:27500:410:420:28009
+Via 1 - Sch ner Re:12148:h:0:27500:511:512:44
+Home Order Tel:12480:v:0:27500:1279:1280:40
+QVC GERMANY:12552:v:0:22000:165:166:12100
+TW 1:12692:h:0:22000:166:167:13013
+Canal Canarias:12441:v:0:27500:513:681:29700
+ProSieben A:12051:v:0:27500:161:84:20002
+ProSieben CH:12051:v:0:27500:289:290:20001
+Kabel 1 Austria:12051:v:0:27500:166:167:20004
+Kabel 1 Schweiz:12051:v:0:27500:162:163:20003
+CNN Int.:12168:v:0:27500:165:100:28512
+Sky News:12552:v:0:22000:305:306:3995
+Travel:12168:v:0:27500:163:92:28001
+AB SAT / XXL:12266:h:0:27500:164:96:17004
+MOTEURS:12266:h:0:27500:160:80:17000
+HOT GM:12148:h:0:27500:767:768:45
+KTO:12129:v:0:27500:170:120:8411
+LA CINQUIEME:12207:v:0:27500:160:80:8501
+LCP:12207:v:0:27500:165:100:8506
+LibertyTV.com:12611:v:0:22000:941:942:12280
+TV5 Europe:12611:v:0:22000:45:46:12240
+Motors TV:12611:v:0:22000:191:194:12300
+Wishline:12611:v:0:22000:214:216:12320
+TV 5:10786:v:0:21997:164:112:9001
+RTM - MAROC:10786:v:0:21997:162:96:9002
+ESC1 - EGYPTE:10786:v:0:21997:163:104:9003
+RAI 1:10786:v:0:21997:289:290:9004
+RTPI:10786:v:0:21997:300:301:9006
+TV7:10786:v:0:21997:166:128:9007
+ARTE:10786:v:0:21997:167:136:9009
+Colourbars:12611:v:0:22000:48:49:3982
+Alice:12611:v:0:22000:162:96:12200
+Video Italia:12611:v:0:22000:121:122:12220
+ANDALUCIA TV:11934:v:0:27500:166:104:29011
+TVC INT.:12441:v:0:27500:512:660:29701
+TV4:11992:h:0:27500:165:98:20365
+TV Niepokalanow:11876:h:0:27500:161:82:20601
+VIVA:12670:v:0:22000:309:310:12732
+VIVA ZWEI:12552:v:0:22000:171:172:12120
+MTV Central:12699:v:0:22000:3031:3032:28643
+ONYX:12692:h:1:27500:161:84:502
+VIVA polska:11603:h:1:27500:190:191:611
+DeeJay TV:11603:h:1:27500:160:161:602
+NBC:11053:h:1:27500:550:551:8008
+EWTN:10722:h:1:29900:1001:1201:4601
+MTA INTL:10722:h:1:29900:1004:1204:4604
+VOX:11053:h:1:27500:500:501:8002
+SAT.1 A:11053:h:1:27500:511:512:8003
+RTL2 AUSTRIA:11053:h:1:27500:520:521:8004
+ZDF:11053:h:1:27500:570:571:8011
+K-TV:11053:h:1:27500:580:581:8012
+RTL Television:11053:h:1:27500:160:80:8001
+ARTE:11059:v:1:6510:98:99:1
+HOT Italia:11095:h:1:27500:4194:4195:3714
+Olisat:11095:h:1:27500:33:34:3718
+VIVA-POLSKA:11128:h:1:4340:98:99:1
+DW-tv:11195:v:1:9099:101:102:5301
+Canal 24 Horas:11203:h:1:3999:4130:4131:5301
+TV5:11337:v:1:5631:512:640:1
+SAT.1 CH:11603:h:1:27500:101:102:601
+KurdSat:11603:h:1:27500:111:112:603
+ARD "Das Erste":11603:h:1:27500:172:173:606
+RTL 2 CH:11603:h:1:27500:175:176:609
+Super RTL A:11603:h:1:27500:180:181:610
+TV ROMANIA:11622:v:1:27500:227:247:10707
+MRTV:11622:v:1:27500:222:242:10702
+102.5 HIT Ch:11622:v:1:27500:224:244:10704
+TLC SAT:11622:v:1:27500:225:245:10705
+PRO-SAT:11622:v:1:27500:246:226:10706
+Channel SUN:11622:v:1:27500:229:249:10709
+Racing Channel:11622:v:1:27500:228:248:10708
+3 ABN:11622:v:1:27500:221:241:10701
+Bloom.Germany:11642:h:1:27500:1460:1420:4
+Bloomberg TV UK:11642:h:1:27500:1560:1520:4
+Sat 7:11642:h:1:27500:1660:1620:4
+EDTV 1:11746:h:1:27500:4130:4131:9501
+EDTV SPORT:11746:h:1:27500:4386:4387:9502
+EDTV BUSINESS:11746:h:1:27500:4642:4643:9503
+EDTV DRAMA:11746:h:1:27500:4898:4899:9504
+RAI1:11765:v:1:27499:160:80:3401
+RAI2:11765:v:1:27499:161:84:3402
+RAI3:11765:v:1:27499:162:88:3403
+RaiWayTEST2:11765:v:1:27499:516:654:3405
+RAIMOSAICO:11765:v:1:27499:518:8191:3407
+RAINews24:11803:v:1:27500:516:654:3301
+CAMERA DEPUTATI:11803:v:1:27500:517:655:3302
+TELEPACE:11803:v:1:27500:515:653:3304
+RAISPORTSAT:11803:v:1:27500:512:650:3305
+RAINettunoSAT2:11803:v:1:27500:513:651:3306
+RAIeducational:11803:v:1:27500:514:652:3307
+RAINettunoSAT1:11803:v:1:27500:519:657:3308
+SAT2000:11803:v:1:27500:518:656:3309
+I1:11918:v:1:27499:512:650:1
+C5:11918:v:1:27499:513:660:2
+R4:11918:v:1:27499:514:670:3
+Telesierra:12091:h:1:27500:4160:4161:8704
+C. Milagro:12091:h:1:27500:4368:4369:8711
+Italia Sat:12091:h:1:27500:4600:4601:8728
+TVE Internacional:12091:h:1:27500:4208:4209:8707
+Fiesta:12091:h:1:27500:4432:4433:8720
+Retelsat:12091:h:1:27500:4464:4465:8722
+ART EUROPE:12013:h:1:27495:164:96:450
+EGYPT SAT. CH. 2:12013:h:1:27495:166:104:470
+IQRA:12013:h:1:27495:168:112:474
+MAURITANIA TV:12110:v:1:27500:230:231:704
+ARMENIA TV:12110:v:1:27500:240:241:705
+SAILING CHANNEL:12110:v:1:27500:260:261:707
+AL JAZEERA:12110:v:1:27500:270:271:708
+Coming Soon TV:12110:v:1:27500:310:311:717
+SaluteBenessere:12110:v:1:27500:320:321:718
+AH-EDP1:12148:v:1:27499:96:97:7201
+AH-EDP2:12148:v:1:27499:112:113:7202
+Espresso:12148:v:1:27499:192:193:7203
+Alice:12148:v:1:27499:160:161:7220
+Nuvolari:12148:v:1:27499:176:177:7221
+Leonardo:12148:v:1:27499:128:129:7222
+AH-EDP3:12148:v:1:27499:36:37:7205
+OTE Promo:12187:v:1:27500:517:655:1001
+RTS SAT:12187:v:1:27500:519:657:1022
+ERT SAT:12187:v:1:27500:514:652:1102
+EXTRA:12187:v:1:27500:516:654:1106
+TRIAL:12187:v:1:27500:513:651:1108
+Minimax:11303:h:1:19540:300:301:3
+TVN1:12209:h:1:5631:4194:4195:1
+RR TEST:10978:v:1:8998:33:34:1
+TV 5 Thailand:10978:v:1:8998:1057:1058:2
+TEST-1:10978:v:1:8998:3105:3106:4
+FASHION:12244:h:1:27500:123:133:103
+AJARA TV:12244:h:1:27500:127:137:107
+SLO-TV1:12300:v:1:27495:200:201:3201
+POLONIA 1:12302:v:1:27500:205:206:3203
+SUPER 1:12302:v:1:27500:207:208:3207
+NAPOLI INT.:12302:v:1:27500:240:241:3210
+MAGIC:12302:v:1:27500:245:246:3211
+COUNTDOWN:12302:v:1:27500:235:236:3212
+TBNE:12302:v:1:27500:230:231:3213
+NAPOLI CHANNEL:12302:v:1:27500:227:228:3215
+KURDISTAN TV:12302:v:1:27500:225:226:3214
+ATLAS TV:12379:v:1:27500:3022:3032:3002
+TELE 24 SWITZERLAND:12379:v:1:27500:3023:3033:3003
+Abu Dhabi TV:12379:v:1:27500:3024:3034:3004
+RTV MONTENEGRO:12379:v:1:27500:3026:3036:3006
+JAAM-E-JAM 1:12436:h:1:27500:160:80:1
+JAAM-E-JAM 2:12436:h:1:27500:161:82:2
+SAHAR:12436:h:1:27500:162:84:3
+SAHAR 2:12436:h:1:27500:163:86:4
+IRINN:12436:h:1:27500:164:88:5
+Musicmax:11303:h:1:19540:500:501:6
+TEST:12474:h:1:27500:771:8191:10608
+EbS:12474:h:1:27500:101:201:10601
+MOU.2:12474:h:1:27500:42:43:10602
+PINK PLUS:12474:h:1:27500:308:256:10605
+LibertyTV.com:12474:h:1:27500:941:942:10603
+2M Maroc:12474:h:1:27500:601:602:10607
+ZEE TV:12474:h:1:27500:910:911:10604
+WorldNet Europe:12483:v:1:8299:4260:4220:1
+WorldNet:12483:v:1:8299:4560:4520:4
+SICILIA INTERNATIONA:12519:v:1:27499:501:502:8309
+SARDEGNA UNO:12519:v:1:27499:503:504:8310
+EuroMed:12519:v:1:27499:510:511:8312
+TGRT:12519:v:1:27499:505:506:8313
+VIDEOLINA:12519:v:1:27499:515:516:8318
+MEDIOLANUM:12538:h:1:27500:1131:1132:8987
+www.travel:12538:h:1:27500:1180:1183:8992
+MonteCarloSat:12538:h:1:27500:5126:5122:8877
+Bulgaria TV:12538:h:1:27500:4612:4613:8827
+TVN1:12571:h:1:5631:4194:4195:1
+JSTV 1:12595:v:1:27500:2000:2001:8213
+JSTV 2:12595:v:1:27500:2011:2013:8214
+MBC:12595:v:1:27500:160:80:8201
+ANN:12595:v:1:27500:161:84:8202
+BET:12595:v:1:27500:167:108:8208
+EuroNews:12595:v:1:27500:2221:2231:8211
+Sharjah Arabs:12653:h:1:27500:1160:1120:1
+Qatar Arabs:12653:h:1:27500:1260:1220:2
+Saudi 1 Arabs:12653:h:1:27500:1360:1320:3
+Kuwait Arabs:12653:h:1:27500:1460:1420:4
+Libya Arabs:12653:h:1:27500:1560:1520:5
+Sudan Arabs:12653:h:1:27500:1660:1620:6
+Oman Arabs:12653:h:1:27500:1760:1720:7
+Jordan Arabs:12653:h:1:27500:1860:1820:8
+IRAQ TV:12653:h:1:27500:1960:1920:9
+Dubai Sport:12653:h:1:27500:1060:1020:10
+Digitaly:12672:v:1:27500:220:221:4203
+Telemarket:12672:v:1:27500:350:351:4211
+eVision:12672:v:1:27500:360:361:4214
+Thai TV5:12672:v:1:27500:200:201:4201
+Studio Europa:12672:v:1:27500:230:231:4204
+Video Italia:12672:v:1:27500:340:341:4210
+GAME NETWORK:12672:v:1:27500:291:292:4213
+BBC-Choice:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621
+BBC-Knowledge:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:630:631
+BBC-News24:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641
+BBC-1:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601
+BBC-Parliament:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660
+BBC-2:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611
+ITV-1:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:513:651
+ITV-2:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2818:2819
+ITV-Sport:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2836:2837
+FilmFour:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2822:2823
+C4:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2826:2827
+E4:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2831:2832
+C5:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018
+Shop:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050
+ITVSelect-Info:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6065:6066
+ITVSelect-1:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6081:6082
+ITVSelect-2:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6097:6098
+ITVSelect-3:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6113:6114
+ITVSelect-4:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6129:6130
+Carlton-Cinema:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289
+Sky-One:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545
+Sky-Sports-1:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801
+Sky-Premier:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1056:1057
+CartoonNetwork:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313
+UK-Horizons:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2336:2337
+ITV-Sport-Plus:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2592:2593
+ITVSportSelect:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:2596
+BreezeMen&Mtrs:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801
+Granada-Plus:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545
+MTV:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1568:1569
+Sky-Movie-Max:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313
+Sky-Sports-2:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2080:2081
+UK-Gold:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289
+Wellbeing:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1824:1825
+PLAY-uk:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289
+UK-Style:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545
+no-name:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801
+Discovery:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313
+Nick/Paramount:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2080:2081
+Sky-Sports-3:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2336:2337
+Brit-Eurosport:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2592:2593
diff --git a/test/libdvben50221/Makefile b/test/libdvben50221/Makefile
new file mode 100644
index 0000000..cd29679
--- /dev/null
+++ b/test/libdvben50221/Makefile
@@ -0,0 +1,14 @@
+# Makefile for linuxtv.org dvb-apps/test/libdvben50221
+
+binaries = test-app \
+ test-session \
+ test-transport
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbapi/libdvbapi.a ../../lib/libdvben50221/libdvben50221.a ../../lib/libucsi/libucsi.a -lpthread
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libdvben50221/test-app.c b/test/libdvben50221/test-app.c
new file mode 100644
index 0000000..d99ec01
--- /dev/null
+++ b/test/libdvben50221/test-app.c
@@ -0,0 +1,854 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <libdvben50221/en50221_session.h>
+#include <libdvben50221/en50221_app_utils.h>
+#include <libdvben50221/en50221_app_ai.h>
+#include <libdvben50221/en50221_app_auth.h>
+#include <libdvben50221/en50221_app_ca.h>
+#include <libdvben50221/en50221_app_datetime.h>
+#include <libdvben50221/en50221_app_dvb.h>
+#include <libdvben50221/en50221_app_epg.h>
+#include <libdvben50221/en50221_app_lowspeed.h>
+#include <libdvben50221/en50221_app_mmi.h>
+#include <libdvben50221/en50221_app_rm.h>
+#include <libdvben50221/en50221_app_smartcard.h>
+#include <libdvben50221/en50221_app_teletext.h>
+#include <libdvbapi/dvbca.h>
+#include <pthread.h>
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libucsi/section.h>
+#include <libucsi/mpeg/section.h>
+
+#define DEFAULT_SLOT 0
+
+#define MAX_SESSIONS 256
+#define MAX_TC 32
+
+void *stackthread_func(void* arg);
+void *pmtthread_func(void* arg);
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id);
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id);
+
+int test_datetime_enquiry_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t response_interval);
+
+int test_rm_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number);
+int test_rm_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *resource_ids);
+int test_rm_changed_callback(void *arg, uint8_t slot_id, uint16_t session_number);
+
+int test_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string);
+
+int test_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids);
+int test_ca_pmt_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_pmt_reply *reply, uint32_t reply_size);
+
+int test_mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t cmd_id, uint8_t delay);
+
+int test_mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t mmi_mode);
+
+int test_mmi_keypad_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t *key_codes, uint32_t key_codes_count);
+
+int test_mmi_subtitle_segment_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size);
+
+int test_mmi_scene_end_mark_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t send_scene_done, uint8_t scene_tag);
+
+int test_mmi_scene_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t scene_tag);
+
+int test_mmi_subtitle_download_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size);
+
+int test_mmi_flush_download_callback(void *arg, uint8_t slot_id, uint16_t session_number);
+
+int test_mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t blind_answer, uint8_t expected_answer_length,
+ uint8_t *text, uint32_t text_size);
+
+int test_mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw);
+
+int test_app_mmi_list_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw);
+
+struct section_ext *read_section_ext(char *buf, int buflen, int adapter, int demux, int pid, int table_id);
+
+
+
+
+
+
+
+int adapterid;
+
+int shutdown_stackthread = 0;
+int shutdown_pmtthread = 0;
+int in_menu = 0;
+int in_enq = 0;
+int ca_connected = 0;
+int pmt_pid = -1;
+int ca_session_number = 0;
+
+
+// instances of resources we actually implement here
+struct en50221_app_rm *rm_resource;
+struct en50221_app_datetime *datetime_resource;
+struct en50221_app_ai *ai_resource;
+struct en50221_app_ca *ca_resource;
+struct en50221_app_mmi *mmi_resource;
+
+// lookup table used in resource manager implementation
+struct resource {
+ struct en50221_app_public_resource_id resid;
+ uint32_t binary_resource_id;
+ en50221_sl_resource_callback callback;
+ void *arg;
+};
+struct resource resources[20];
+int resources_count = 0;
+
+// this contains all known resource ids so we can see if the cam asks for something exotic
+uint32_t resource_ids[] = { EN50221_APP_TELETEXT_RESOURCEID,
+ EN50221_APP_SMARTCARD_RESOURCEID(1),
+ EN50221_APP_RM_RESOURCEID,
+ EN50221_APP_MMI_RESOURCEID,
+ EN50221_APP_LOWSPEED_RESOURCEID(1,1),
+ EN50221_APP_EPG_RESOURCEID(1),
+ EN50221_APP_DVB_RESOURCEID,
+ EN50221_APP_CA_RESOURCEID,
+ EN50221_APP_DATETIME_RESOURCEID,
+ EN50221_APP_AUTH_RESOURCEID,
+ EN50221_APP_AI_RESOURCEID, };
+int resource_ids_count = sizeof(resource_ids)/4;
+
+
+uint16_t ai_session_numbers[5];
+
+uint16_t mmi_session_number;
+
+int main(int argc, char * argv[])
+{
+ pthread_t stackthread;
+ pthread_t pmtthread;
+ struct en50221_app_send_functions sendfuncs;
+
+ if ((argc < 2) || (argc > 3)) {
+ fprintf(stderr, "Syntax: test-app <adapterid> [<pmtpid>]\n");
+ exit(1);
+ }
+ adapterid = atoi(argv[1]);
+ if (argc == 3) {
+ if (sscanf(argv[2], "%i", &pmt_pid) != 1) {
+ fprintf(stderr, "Unable to parse PMT PID\n");
+ exit(1);
+ }
+ }
+
+ // create transport layer
+ struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ exit(1);
+ }
+
+ // find CAMs
+ int cafd;
+ if (((cafd = dvbca_open(adapterid, 0)) < 0) || (dvbca_get_cam_state(cafd, DEFAULT_SLOT) == DVBCA_CAMSTATE_MISSING)) {
+ fprintf(stderr, "Unable to open CAM on adapter %i\n", adapterid);
+ exit(1);
+ }
+
+ // reset it and wait
+ dvbca_reset(cafd, DEFAULT_SLOT);
+ printf("Found a CAM on adapter%i... waiting...\n", adapterid);
+ while(dvbca_get_cam_state(cafd, DEFAULT_SLOT) != DVBCA_CAMSTATE_READY) {
+ usleep(1000);
+ }
+
+ // register it with the CA stack
+ int slot_id = 0;
+ if ((slot_id = en50221_tl_register_slot(tl, cafd, DEFAULT_SLOT, 1000, 100)) < 0) {
+ fprintf(stderr, "Slot registration failed\n");
+ exit(1);
+ }
+ printf("slotid: %i\n", slot_id);
+
+ // create session layer
+ struct en50221_session_layer *sl = en50221_sl_create(tl, 256);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ exit(1);
+ }
+
+ // create the sendfuncs
+ sendfuncs.arg = sl;
+ sendfuncs.send_data = (en50221_send_data) en50221_sl_send_data;
+ sendfuncs.send_datav = (en50221_send_datav) en50221_sl_send_datav;
+
+ // create the resource manager resource
+ rm_resource = en50221_app_rm_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_RM_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_RM_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_rm_message;
+ resources[resources_count].arg = rm_resource;
+ en50221_app_rm_register_enq_callback(rm_resource, test_rm_enq_callback, NULL);
+ en50221_app_rm_register_reply_callback(rm_resource, test_rm_reply_callback, NULL);
+ en50221_app_rm_register_changed_callback(rm_resource, test_rm_changed_callback, NULL);
+ resources_count++;
+
+ // create the datetime resource
+ datetime_resource = en50221_app_datetime_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_DATETIME_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_DATETIME_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_datetime_message;
+ resources[resources_count].arg = datetime_resource;
+ en50221_app_datetime_register_enquiry_callback(datetime_resource, test_datetime_enquiry_callback, NULL);
+ resources_count++;
+
+ // create the application information resource
+ ai_resource = en50221_app_ai_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_AI_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_AI_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_ai_message;
+ resources[resources_count].arg = ai_resource;
+ en50221_app_ai_register_callback(ai_resource, test_ai_callback, NULL);
+ resources_count++;
+
+ // create the CA resource
+ ca_resource = en50221_app_ca_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_CA_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_CA_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_ca_message;
+ resources[resources_count].arg = ca_resource;
+ en50221_app_ca_register_info_callback(ca_resource, test_ca_info_callback, NULL);
+ en50221_app_ca_register_pmt_reply_callback(ca_resource, test_ca_pmt_reply_callback, NULL);
+ resources_count++;
+
+ // create the MMI resource
+ mmi_resource = en50221_app_mmi_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_MMI_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_MMI_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_mmi_message;
+ resources[resources_count].arg = mmi_resource;
+ en50221_app_mmi_register_close_callback(mmi_resource, test_mmi_close_callback, NULL);
+ en50221_app_mmi_register_display_control_callback(mmi_resource, test_mmi_display_control_callback, NULL);
+ en50221_app_mmi_register_keypad_control_callback(mmi_resource, test_mmi_keypad_control_callback, NULL);
+ en50221_app_mmi_register_subtitle_segment_callback(mmi_resource, test_mmi_subtitle_segment_callback, NULL);
+ en50221_app_mmi_register_scene_end_mark_callback(mmi_resource, test_mmi_scene_end_mark_callback, NULL);
+ en50221_app_mmi_register_scene_control_callback(mmi_resource, test_mmi_scene_control_callback, NULL);
+ en50221_app_mmi_register_subtitle_download_callback(mmi_resource, test_mmi_subtitle_download_callback, NULL);
+ en50221_app_mmi_register_flush_download_callback(mmi_resource, test_mmi_flush_download_callback, NULL);
+ en50221_app_mmi_register_enq_callback(mmi_resource, test_mmi_enq_callback, NULL);
+ en50221_app_mmi_register_menu_callback(mmi_resource, test_mmi_menu_callback, NULL);
+ en50221_app_mmi_register_list_callback(mmi_resource, test_app_mmi_list_callback, NULL);
+ resources_count++;
+
+ // start another thread running the stack
+ pthread_create(&stackthread, NULL, stackthread_func, tl);
+
+ // start another thread parsing PMT
+ if (pmt_pid != -1) {
+ pthread_create(&pmtthread, NULL, pmtthread_func, tl);
+ }
+
+ // register callbacks
+ en50221_sl_register_lookup_callback(sl, test_lookup_callback, sl);
+ en50221_sl_register_session_callback(sl, test_session_callback, sl);
+
+ // create a new connection on each slot
+ int tc = en50221_tl_new_tc(tl, slot_id);
+ printf("tcid: %i\n", tc);
+
+ printf("Press a key to enter menu\n");
+ getchar();
+ en50221_app_ai_entermenu(ai_resource, ai_session_numbers[slot_id]);
+
+ // wait
+ char tmp[256];
+ while(1) {
+ fgets(tmp, sizeof(tmp), stdin);
+ int choice = atoi(tmp);
+
+ if (in_menu) {
+ en50221_app_mmi_menu_answ(mmi_resource, mmi_session_number, choice);
+ in_menu = 0;
+ }
+ if (in_enq) {
+ uint32_t i;
+ uint32_t len = strlen(tmp);
+ for(i=0; i< len; i++) {
+ if (!isdigit(tmp[i])) {
+ len = i;
+ break;
+ }
+ }
+ en50221_app_mmi_answ(mmi_resource, mmi_session_number, MMI_ANSW_ID_ANSWER, (uint8_t*) tmp, len);
+ in_enq = 0;
+ }
+ }
+ printf("Press a key to exit\n");
+ getchar();
+
+ // destroy slots
+ en50221_tl_destroy_slot(tl, slot_id);
+ shutdown_stackthread = 1;
+ shutdown_pmtthread = 1;
+ pthread_join(stackthread, NULL);
+ if (pmt_pid != -1) {
+ pthread_join(pmtthread, NULL);
+ }
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ return 0;
+}
+
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id)
+{
+ struct en50221_app_public_resource_id resid;
+ (void)arg;
+
+ // decode the resource id
+ if (en50221_app_decode_public_resource_id(&resid, requested_resource_id)) {
+ printf("%02x:Public resource lookup callback %i %i %i\n", slot_id,
+ resid.resource_class, resid.resource_type, resid.resource_version);
+ } else {
+ printf("%02x:Private resource lookup callback %08x\n", slot_id, requested_resource_id);
+ return -1;
+ }
+
+ // FIXME: need better comparison
+ // FIXME: return resourceid we actually connected to
+
+ // try and find an instance of the resource
+ int i;
+ for(i=0; i<resources_count; i++) {
+ if ((resid.resource_class == resources[i].resid.resource_class) &&
+ (resid.resource_type == resources[i].resid.resource_type)) {
+ *callback_out = resources[i].callback;
+ *arg_out = resources[i].arg;
+ *connected_resource_id = resources[i].binary_resource_id;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id)
+{
+ (void)arg;
+ switch(reason) {
+ case S_SCALLBACK_REASON_CAMCONNECTING:
+ printf("%02x:CAM connecting to resource %08x, session_number %i\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_CAMCONNECTED:
+ printf("%02x:CAM successfully connected to resource %08x, session_number %i\n",
+ slot_id, resource_id, session_number);
+
+ if (resource_id == EN50221_APP_RM_RESOURCEID) {
+ en50221_app_rm_enq(rm_resource, session_number);
+ } else if (resource_id == EN50221_APP_AI_RESOURCEID) {
+ en50221_app_ai_enquiry(ai_resource, session_number);
+ } else if (resource_id == EN50221_APP_CA_RESOURCEID) {
+ en50221_app_ca_info_enq(ca_resource, session_number);
+ ca_session_number = session_number;
+ }
+
+ break;
+ case S_SCALLBACK_REASON_CAMCONNECTFAIL:
+ printf("%02x:CAM on failed to connect to resource %08x\n", slot_id, resource_id);
+ break;
+ case S_SCALLBACK_REASON_CONNECTED:
+ printf("%02x:Host connection to resource %08x connected successfully, session_number %i\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_CONNECTFAIL:
+ printf("%02x:Host connection to resource %08x failed, session_number %i\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_CLOSE:
+ printf("%02x:Connection to resource %08x, session_number %i closed\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_TC_CONNECT:
+ printf("%02x:Host originated transport connection %i connected\n", slot_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_TC_CAMCONNECT:
+ printf("%02x:CAM originated transport connection %i connected\n", slot_id, session_number);
+ break;
+ }
+ return 0;
+}
+
+
+
+int test_rm_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number)
+{
+ (void)arg;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ if (en50221_app_rm_reply(rm_resource, session_number, resource_ids_count, resource_ids)) {
+ printf("%02x:Failed to send reply to ENQ\n", slot_id);
+ }
+
+ return 0;
+}
+
+int test_rm_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *_resource_ids)
+{
+ (void)arg;
+ printf("%02x:%s\n", slot_id, __func__);
+
+ uint32_t i;
+ for(i=0; i< resource_id_count; i++) {
+ printf(" CAM provided resource id: %08x\n", _resource_ids[i]);
+ }
+
+ if (en50221_app_rm_changed(rm_resource, session_number)) {
+ printf("%02x:Failed to send REPLY\n", slot_id);
+ }
+
+ return 0;
+}
+
+int test_rm_changed_callback(void *arg, uint8_t slot_id, uint16_t session_number)
+{
+ (void)arg;
+ printf("%02x:%s\n", slot_id, __func__);
+
+ if (en50221_app_rm_enq(rm_resource, session_number)) {
+ printf("%02x:Failed to send ENQ\n", slot_id);
+ }
+
+ return 0;
+}
+
+
+
+int test_datetime_enquiry_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t response_interval)
+{
+ (void)arg;
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" response_interval:%i\n", response_interval);
+
+ if (en50221_app_datetime_send(datetime_resource, session_number, time(NULL), -1)) {
+ printf("%02x:Failed to send datetime\n", slot_id);
+ }
+
+ return 0;
+}
+
+
+
+int test_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string)
+{
+ (void)arg;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" Application type: %02x\n", application_type);
+ printf(" Application manufacturer: %04x\n", application_manufacturer);
+ printf(" Manufacturer code: %04x\n", manufacturer_code);
+ printf(" Menu string: %.*s\n", menu_string_length, menu_string);
+
+ ai_session_numbers[slot_id] = session_number;
+
+ return 0;
+}
+
+
+
+int test_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ uint32_t i;
+ for(i=0; i< ca_id_count; i++) {
+ printf(" Supported CA ID: %04x\n", ca_ids[i]);
+ }
+
+ ca_connected = 1;
+ return 0;
+}
+
+int test_ca_pmt_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_pmt_reply *reply, uint32_t reply_size)
+{
+ (void)arg;
+ (void)session_number;
+ (void)reply;
+ (void)reply_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+
+int test_mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t cmd_id, uint8_t delay)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" cmd_id: %02x\n", cmd_id);
+ printf(" delay: %02x\n", delay);
+
+ return 0;
+}
+
+int test_mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t mmi_mode)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" cmd_id: %02x\n", cmd_id);
+ printf(" mode: %02x\n", mmi_mode);
+
+ if (cmd_id == MMI_DISPLAY_CONTROL_CMD_ID_SET_MMI_MODE) {
+ struct en50221_app_mmi_display_reply_details details;
+
+ details.u.mode_ack.mmi_mode = mmi_mode;
+ if (en50221_app_mmi_display_reply(mmi_resource, session_number, MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK, &details)) {
+ printf("%02x:Failed to send mode ack\n", slot_id);
+ }
+ }
+
+ return 0;
+}
+
+int test_mmi_keypad_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t *key_codes, uint32_t key_codes_count)
+{
+ (void)arg;
+ (void)session_number;
+ (void)cmd_id;
+ (void)key_codes;
+ (void)key_codes_count;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_subtitle_segment_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size)
+{
+ (void)arg;
+ (void)session_number;
+ (void)segment;
+ (void)segment_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_scene_end_mark_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t send_scene_done, uint8_t scene_tag)
+{
+ (void)arg;
+ (void)session_number;
+ (void)decoder_continue_flag;
+ (void)scene_reveal_flag;
+ (void)send_scene_done;
+ (void)scene_tag;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_scene_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t scene_tag)
+{
+ (void)arg;
+ (void)session_number;
+ (void)decoder_continue_flag;
+ (void)scene_reveal_flag;
+ (void)scene_tag;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_subtitle_download_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size)
+{
+ (void)arg;
+ (void)session_number;
+ (void)segment;
+ (void)segment_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_flush_download_callback(void *arg, uint8_t slot_id, uint16_t session_number)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t blind_answer, uint8_t expected_answer_length,
+ uint8_t *text, uint32_t text_size)
+{
+ (void)arg;
+ (void)text;
+ (void)text_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" blind: %i\n", blind_answer);
+ printf(" expected_answer_length: %i\n", expected_answer_length);
+
+ mmi_session_number = session_number;
+ in_enq = 1;
+
+ return 0;
+}
+
+int test_mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw)
+{
+ (void)arg;
+ (void)items_raw;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ printf(" title: %.*s\n", title->text_length, title->text);
+ printf(" sub_title: %.*s\n", sub_title->text_length, sub_title->text);
+ printf(" bottom: %.*s\n", bottom->text_length, bottom->text);
+
+ uint32_t i;
+ for(i=0; i< item_count; i++) {
+ printf(" item %i: %.*s\n", i+1, items[i].text_length, items[i].text);
+ }
+ printf(" raw_length: %i\n", item_raw_length);
+
+ mmi_session_number = session_number;
+ in_menu = 1;
+
+ return 0;
+}
+
+int test_app_mmi_list_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw)
+{
+ (void)arg;
+ (void)items_raw;
+ (void)arg;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ printf(" title: %.*s\n", title->text_length, title->text);
+ printf(" sub_title: %.*s\n", sub_title->text_length, sub_title->text);
+ printf(" bottom: %.*s\n", bottom->text_length, bottom->text);
+
+ uint32_t i;
+ for(i=0; i< item_count; i++) {
+ printf(" item %i: %.*s\n", i+1, items[i].text_length, items[i].text);
+ }
+ printf(" raw_length: %i\n", item_raw_length);
+
+ mmi_session_number = session_number;
+ in_menu = 1;
+
+ return 0;
+}
+
+
+
+
+
+
+
+void *stackthread_func(void* arg) {
+ struct en50221_transport_layer *tl = arg;
+ int lasterror = 0;
+
+ while(!shutdown_stackthread) {
+ int error;
+ if ((error = en50221_tl_poll(tl)) != 0) {
+ if (error != lasterror) {
+ fprintf(stderr, "Error reported by stack slot:%i error:%i\n",
+ en50221_tl_get_error_slot(tl),
+ en50221_tl_get_error(tl));
+ }
+ lasterror = error;
+ }
+ }
+
+ shutdown_stackthread = 0;
+ return 0;
+}
+
+void *pmtthread_func(void* arg) {
+ (void)arg;
+ char buf[4096];
+ uint8_t capmt[4096];
+ int pmtversion = -1;
+
+ while(!shutdown_pmtthread) {
+
+ if (!ca_connected) {
+ sleep(1);
+ continue;
+ }
+
+ // read the PMT
+ struct section_ext *section_ext = read_section_ext(buf, sizeof(buf), adapterid, 0, pmt_pid, stag_mpeg_program_map);
+ if (section_ext == NULL) {
+ fprintf(stderr, "Failed to read PMT\n");
+ exit(1);
+ }
+ struct mpeg_pmt_section *pmt = mpeg_pmt_section_codec(section_ext);
+ if (pmt == NULL) {
+ fprintf(stderr, "Bad PMT received\n");
+ exit(1);
+ }
+ if (pmt->head.version_number == pmtversion) {
+ continue;
+ }
+
+ // translate it into a CA PMT
+ int listmgmt = CA_LIST_MANAGEMENT_ONLY;
+ if (pmtversion != -1) {
+ listmgmt = CA_LIST_MANAGEMENT_UPDATE;
+ }
+ int size;
+ if ((size = en50221_ca_format_pmt(pmt,
+ capmt,
+ sizeof(capmt),
+ listmgmt,
+ 0,
+ CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
+ fprintf(stderr, "Failed to format CA PMT object\n");
+ exit(1);
+ }
+
+ // set it
+ if (en50221_app_ca_pmt(ca_resource, ca_session_number, capmt, size)) {
+ fprintf(stderr, "Failed to send CA PMT object\n");
+ exit(1);
+ }
+ pmtversion = pmt->head.version_number;
+ }
+ shutdown_pmtthread = 0;
+ return 0;
+}
+
+
+struct section_ext *read_section_ext(char *buf, int buflen, int adapter, int demux, int pid, int table_id)
+{
+ int demux_fd = -1;
+ uint8_t filter[18];
+ uint8_t mask[18];
+ int size;
+ struct section *section;
+ struct section_ext *result = NULL;
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ goto exit;
+ }
+
+ // create a section filter
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = table_id;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(demux_fd, pid, filter, mask, 1, 1)) {
+ goto exit;
+ }
+
+ // read the section
+ if ((size = read(demux_fd, buf, buflen)) < 0) {
+ goto exit;
+ }
+
+ // parse it as a section
+ section = section_codec((uint8_t*) buf, size);
+ if (section == NULL) {
+ goto exit;
+ }
+
+ // parse it as a section_ext
+ result = section_ext_decode(section, 0);
+
+exit:
+ if (demux_fd != -1)
+ close(demux_fd);
+ return result;
+}
diff --git a/test/libdvben50221/test-session.c b/test/libdvben50221/test-session.c
new file mode 100644
index 0000000..14dc13e
--- /dev/null
+++ b/test/libdvben50221/test-session.c
@@ -0,0 +1,171 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <libdvben50221/en50221_session.h>
+#include <libdvben50221/en50221_app_utils.h>
+#include <libdvbapi/dvbca.h>
+#include <pthread.h>
+
+void *stackthread_func(void* arg);
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id);
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id);
+
+
+int shutdown_stackthread = 0;
+
+#define DEFAULT_SLOT 0
+
+int main(int argc, char * argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ int i;
+ pthread_t stackthread;
+
+ // create transport layer
+ struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ exit(1);
+ }
+
+ // find CAMs
+ int slot_count = 0;
+ int cafd= -1;
+ for(i=0; i<20; i++) {
+ if ((cafd = dvbca_open(i, 0)) > 0) {
+ if (dvbca_get_cam_state(cafd, DEFAULT_SLOT) == DVBCA_CAMSTATE_MISSING) {
+ close(cafd);
+ continue;
+ }
+
+ // reset it and wait
+ dvbca_reset(cafd, DEFAULT_SLOT);
+ printf("Found a CAM on adapter%i... waiting...\n", i);
+ while(dvbca_get_cam_state(cafd, DEFAULT_SLOT) != DVBCA_CAMSTATE_READY) {
+ usleep(1000);
+ }
+
+ // register it with the CA stack
+ int slot_id = 0;
+ if ((slot_id = en50221_tl_register_slot(tl, cafd, DEFAULT_SLOT, 1000, 100)) < 0) {
+ fprintf(stderr, "Slot registration failed\n");
+ exit(1);
+ }
+ printf("slotid: %i\n", slot_id);
+ slot_count++;
+ }
+ }
+
+ // create session layer
+ struct en50221_session_layer *sl = en50221_sl_create(tl, 256);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ exit(1);
+ }
+
+ // start another thread running the stack
+ pthread_create(&stackthread, NULL, stackthread_func, tl);
+
+ // register callbacks
+ en50221_sl_register_lookup_callback(sl, test_lookup_callback, sl);
+ en50221_sl_register_session_callback(sl, test_session_callback, sl);
+
+ // create a new connection
+ for(i=0; i<slot_count; i++) {
+ int tc = en50221_tl_new_tc(tl, i);
+ printf("tcid: %i\n", tc);
+ }
+
+ // wait
+ printf("Press a key to exit\n");
+ getchar();
+
+ // destroy slots
+ for(i=0; i<slot_count; i++) {
+ en50221_tl_destroy_slot(tl, i);
+ }
+ shutdown_stackthread = 1;
+ pthread_join(stackthread, NULL);
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ return 0;
+}
+
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id)
+{
+ (void)arg;
+ (void)callback_out;
+ (void)arg_out;
+ (void)connected_resource_id;
+
+ struct en50221_app_public_resource_id resid;
+
+ if (en50221_app_decode_public_resource_id(&resid, requested_resource_id)) {
+ printf("Public resource lookup callback %i %i %i %i\n", slot_id,
+ resid.resource_class, resid.resource_type, resid.resource_version);
+ } else {
+ printf("Private resource lookup callback %i %08x\n", slot_id, requested_resource_id);
+ }
+
+ return -1;
+}
+
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id)
+{
+ (void)arg;
+
+ printf("Session callback %i %i %i %04x\n", slot_id, session_number, reason, resource_id);
+
+ return -1;
+}
+
+void *stackthread_func(void* arg) {
+ struct en50221_transport_layer *tl = arg;
+ int lasterror = 0;
+
+ while(!shutdown_stackthread) {
+ int error;
+ if ((error = en50221_tl_poll(tl)) != 0) {
+ if (error != lasterror) {
+ fprintf(stderr, "Error reported by stack slot:%i error:%i\n",
+ en50221_tl_get_error_slot(tl),
+ en50221_tl_get_error(tl));
+ }
+ lasterror = error;
+ }
+ }
+
+ shutdown_stackthread = 0;
+ return 0;
+}
diff --git a/test/libdvben50221/test-transport.c b/test/libdvben50221/test-transport.c
new file mode 100644
index 0000000..fdfd98a
--- /dev/null
+++ b/test/libdvben50221/test-transport.c
@@ -0,0 +1,144 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <libdvben50221/en50221_transport.h>
+#include <libdvbapi/dvbca.h>
+#include <pthread.h>
+
+void *stackthread_func(void* arg);
+void test_callback(void *arg, int reason,
+ uint8_t *data, uint32_t data_length,
+ uint8_t slot_id, uint8_t connection_id);
+
+int shutdown_stackthread = 0;
+
+#define DEFAULT_SLOT 0
+
+int main(int argc, char * argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ int i;
+ pthread_t stackthread;
+
+ // create transport layer
+ struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ exit(1);
+ }
+
+ // find CAMs
+ int slot_count = 0;
+ int cafd= -1;
+ for(i=0; i<20; i++) {
+ if ((cafd = dvbca_open(i, 0)) > 0) {
+ if (dvbca_get_cam_state(cafd, DEFAULT_SLOT) == DVBCA_CAMSTATE_MISSING) {
+ close(cafd);
+ continue;
+ }
+
+ // reset it and wait
+ dvbca_reset(cafd, DEFAULT_SLOT);
+ printf("Found a CAM on adapter%i... waiting...\n", i);
+ while(dvbca_get_cam_state(cafd, DEFAULT_SLOT) != DVBCA_CAMSTATE_READY) {
+ usleep(1000);
+ }
+
+ // register it with the CA stack
+ int slot_id = 0;
+ if ((slot_id = en50221_tl_register_slot(tl, cafd, DEFAULT_SLOT, 1000, 100)) < 0) {
+ fprintf(stderr, "Slot registration failed\n");
+ exit(1);
+ }
+ printf("slotid: %i\n", slot_id);
+ slot_count++;
+ }
+ }
+
+ // start another thread to running the stack
+ pthread_create(&stackthread, NULL, stackthread_func, tl);
+
+ // register callback
+ en50221_tl_register_callback(tl, test_callback, tl);
+
+ // create a new connection
+ for(i=0; i<slot_count; i++) {
+ int tc = en50221_tl_new_tc(tl, i);
+ printf("tcid: %i\n", tc);
+ }
+
+ // wait
+ printf("Press a key to exit\n");
+ getchar();
+
+ // destroy slots
+ for(i=0; i<slot_count; i++) {
+ en50221_tl_destroy_slot(tl, i);
+ }
+ shutdown_stackthread = 1;
+ pthread_join(stackthread, NULL);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ return 0;
+}
+
+void test_callback(void *arg, int reason,
+ uint8_t *data, uint32_t data_length,
+ uint8_t slot_id, uint8_t connection_id)
+{
+ (void) arg;
+
+ printf("-----------------------------------\n");
+ printf("CALLBACK SLOTID:%i %i %i\n", slot_id, connection_id, reason);
+
+ uint32_t i;
+ for(i=0; i< data_length; i++) {
+ printf("%02x %02x\n", i, data[i]);
+ }
+}
+
+void *stackthread_func(void* arg) {
+ struct en50221_transport_layer *tl = arg;
+ int lasterror = 0;
+
+ while(!shutdown_stackthread) {
+ int error;
+ if ((error = en50221_tl_poll(tl)) != 0) {
+ if (error != lasterror) {
+ fprintf(stderr, "Error reported by stack slot:%i error:%i\n",
+ en50221_tl_get_error_slot(tl),
+ en50221_tl_get_error(tl));
+ }
+ lasterror = error;
+ }
+ }
+
+ shutdown_stackthread = 0;
+ return 0;
+}
diff --git a/test/libdvbsec/Makefile b/test/libdvbsec/Makefile
new file mode 100644
index 0000000..27c9c21
--- /dev/null
+++ b/test/libdvbsec/Makefile
@@ -0,0 +1,12 @@
+# Makefile for linuxtv.org dvb-apps/test/libdvbsec
+
+binaries = dvbsec_test
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbsec/libdvbsec.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libdvbsec/dvbsec_test.c b/test/libdvbsec/dvbsec_test.c
new file mode 100644
index 0000000..b49d703
--- /dev/null
+++ b/test/libdvbsec/dvbsec_test.c
@@ -0,0 +1,85 @@
+/**
+ * dvbsec testing.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libdvbsec/dvbsec_cfg.h>
+
+void syntax(void);
+
+struct dvbsec_config *secconfigs = NULL;
+int seccount = 0;
+
+int secload_callback(void *private, struct dvbsec_config *sec);
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4) {
+ syntax();
+ }
+
+ if (!strcmp(argv[1], "-sec")) {
+
+ FILE *f = fopen(argv[2], "r");
+ if (!f) {
+ fprintf(stderr, "Unable to load %s\n", argv[2]);
+ exit(1);
+ }
+ dvbsec_cfg_load(f, NULL, secload_callback);
+ fclose(f);
+
+ f = fopen(argv[3], "w");
+ if (!f) {
+ fprintf(stderr, "Unable to write %s\n", argv[3]);
+ exit(1);
+ }
+ dvbsec_cfg_save(f, secconfigs, seccount);
+ fclose(f);
+
+ } else {
+ syntax();
+ }
+
+ exit(0);
+}
+
+int secload_callback(void *private, struct dvbsec_config *sec)
+{
+ (void) private;
+
+ struct dvbsec_config *tmp = realloc(secconfigs, (seccount+1) * sizeof(struct dvbsec_config));
+ if (tmp == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ secconfigs = tmp;
+
+ memcpy(&secconfigs[seccount++], sec, sizeof(struct dvbsec_config));
+
+ return 0;
+}
+
+void syntax()
+{
+ fprintf(stderr,
+ "Syntax: dvbcfg_test <-zapchannel|-sec> <input filename> <output filename>\n");
+ exit(1);
+}
diff --git a/test/libdvbsec/test_sec.txt b/test/libdvbsec/test_sec.txt
new file mode 100644
index 0000000..1189026
--- /dev/null
+++ b/test/libdvbsec/test_sec.txt
@@ -0,0 +1,28 @@
+[sec]
+name=test1
+switch-frequency=100000
+lof-lo-v=20
+lof-lo-h=30
+lof-lo-l=40
+lof-lo-r=50
+lof-hi-v=60
+lof-hi-h=70
+lof-hi-l=80
+lof-hi-r=90
+config-type=none
+
+[sec]
+name=test2
+switch-frequency=200
+lof-lo-v=40
+lof-hi-h=50
+config-type=simple
+
+[sec]
+name=test3
+switch-frequency=100000
+lof-lo-l=20
+lof-hi-r=30
+config-type=advanced
+cmd-lo-v=MOOVH
+cmd-lo-h=MOOLH
diff --git a/test/libesg/Makefile b/test/libesg/Makefile
new file mode 100644
index 0000000..11d65bd
--- /dev/null
+++ b/test/libesg/Makefile
@@ -0,0 +1,12 @@
+# Makefile for linuxtv.org dvb-apps/test/libucsi
+
+binaries = testesg
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libesg/libesg.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libesg/samples/ESGProviderDiscoveryDescriptor.xml b/test/libesg/samples/ESGProviderDiscoveryDescriptor.xml
new file mode 100644
index 0000000..3989afb
--- /dev/null
+++ b/test/libesg/samples/ESGProviderDiscoveryDescriptor.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<ESGProviderDiscovery xmlns="urn:dvb:ipdc:esgbs:2005" xmlns:mpeg7="urn:mpeg:mpeg7:schema:2001">
+ <ServiceProvider>
+ <ProviderURI>http://www.sidsa.com</ProviderURI>
+ <ProviderName>SIDSA (Multiple Stream)</ProviderName>
+ <ProviderID>1</ProviderID>
+ </ServiceProvider>
+ <ServiceProvider>
+ <ProviderURI>http://www.sidsa.com</ProviderURI>
+ <ProviderName>SIDSA (Single Stream)</ProviderName>
+ <ProviderID>2</ProviderID>
+ </ServiceProvider>
+</ESGProviderDiscovery>
diff --git a/test/libesg/testesg.c b/test/libesg/testesg.c
new file mode 100644
index 0000000..f2183ac
--- /dev/null
+++ b/test/libesg/testesg.c
@@ -0,0 +1,563 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <libesg/bootstrap/access_descriptor.h>
+#include <libesg/encapsulation/container.h>
+#include <libesg/encapsulation/fragment_management_information.h>
+#include <libesg/encapsulation/data_repository.h>
+#include <libesg/encapsulation/string_repository.h>
+#include <libesg/representation/encapsulated_textual_esg_xml_fragment.h>
+#include <libesg/representation/init_message.h>
+#include <libesg/representation/textual_decoder_init.h>
+#include <libesg/representation/bim_decoder_init.h>
+#include <libesg/transport/session_partition_declaration.h>
+
+#define MAX_FILENAME 256
+
+void usage(void) {
+ static const char *_usage =
+ "Usage: testesg [-a <ESGAccessDescriptor>]\n"
+ " [-c <ESGContainer with Textual ESG XML Fragment>]\n"
+ " [-X XXXX]\n";
+
+ fprintf(stderr, "%s", _usage);
+ exit(1);
+}
+
+void read_from_file(const char *filename, char **buffer, int *size) {
+ int fd;
+ struct stat fs;
+
+ if ((fd = open(filename, O_RDONLY)) <= 0) {
+ fprintf(stderr, "File not found\n");
+ exit(1);
+ }
+
+ if (fstat(fd, &fs) < 0) {
+ fprintf(stderr, "File not readable\n");
+ exit(1);
+ }
+ *size = fs.st_size;
+
+ *buffer = (char *) malloc(*size);
+ if (read(fd, *buffer, *size) != *size) {
+ fprintf(stderr, "File read error\n");
+ exit(1);
+ }
+
+ close(fd);
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ char access_descriptor_filename[MAX_FILENAME] = "";
+ char container_filename[MAX_FILENAME] = "";
+ int c;
+ char *buffer = NULL;
+ int size;
+
+ // Read command line options
+ while ((c = getopt(argc, argv, "a:c:")) != -1) {
+ switch (c) {
+ case 'a':
+ strncpy(access_descriptor_filename, optarg, MAX_FILENAME);
+ break;
+ case 'c':
+ strncpy(container_filename, optarg, MAX_FILENAME);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ // ESGAccessDescriptor
+ if (strncmp(access_descriptor_filename, "", MAX_FILENAME) != 0) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "Reading ESG Access Descriptor = %s\n", access_descriptor_filename);
+ fprintf(stdout, "**************************************************\n\n");
+
+ read_from_file(access_descriptor_filename, &buffer, &size);
+
+ struct esg_access_descriptor *access_descriptor = esg_access_descriptor_decode((uint8_t *) buffer, size);
+ free(buffer);
+ if (access_descriptor == NULL) {
+ fprintf(stderr, "ESG Access Descriptor decode error\n");
+ exit(1);
+ }
+ fprintf(stdout, "n_o_ESGEntries %d\n\n", access_descriptor->n_o_entries);
+
+ struct esg_entry *entry;
+ esg_access_descriptor_entry_list_for_each(access_descriptor, entry) {
+ fprintf(stdout, " ESGEntryVersion %d\n", entry->version);
+ fprintf(stdout, " MultipleStreamTransport %d\n", entry->multiple_stream_transport);
+ fprintf(stdout, " IPVersion6 %d\n", entry->ip_version_6);
+ fprintf(stdout, " ProviderID %d\n", entry->provider_id);
+ if (entry->ip_version_6 == 0) {
+ fprintf(stdout, " SourceIPAddress %d.%d.%d.%d\n",
+ entry->source_ip.ipv4[0],
+ entry->source_ip.ipv4[1],
+ entry->source_ip.ipv4[2],
+ entry->source_ip.ipv4[3]);
+ fprintf(stdout, " DestinationIPAddress %d.%d.%d.%d\n",
+ entry->destination_ip.ipv4[0],
+ entry->destination_ip.ipv4[1],
+ entry->destination_ip.ipv4[2],
+ entry->destination_ip.ipv4[3]);
+ } else if (entry->ip_version_6 == 1) {
+ fprintf(stdout, " SourceIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ entry->source_ip.ipv6[0],
+ entry->source_ip.ipv6[1],
+ entry->source_ip.ipv6[2],
+ entry->source_ip.ipv6[3],
+ entry->source_ip.ipv6[4],
+ entry->source_ip.ipv6[5],
+ entry->source_ip.ipv6[6],
+ entry->source_ip.ipv6[7],
+ entry->source_ip.ipv6[8],
+ entry->source_ip.ipv6[9],
+ entry->source_ip.ipv6[10],
+ entry->source_ip.ipv6[11],
+ entry->source_ip.ipv6[12],
+ entry->source_ip.ipv6[13],
+ entry->source_ip.ipv6[14],
+ entry->source_ip.ipv6[15]);
+ fprintf(stdout, " DestinationIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ entry->destination_ip.ipv6[0],
+ entry->destination_ip.ipv6[1],
+ entry->destination_ip.ipv6[2],
+ entry->destination_ip.ipv6[3],
+ entry->destination_ip.ipv6[4],
+ entry->destination_ip.ipv6[5],
+ entry->destination_ip.ipv6[6],
+ entry->destination_ip.ipv6[7],
+ entry->destination_ip.ipv6[8],
+ entry->destination_ip.ipv6[9],
+ entry->destination_ip.ipv6[10],
+ entry->destination_ip.ipv6[11],
+ entry->destination_ip.ipv6[12],
+ entry->destination_ip.ipv6[13],
+ entry->destination_ip.ipv6[14],
+ entry->destination_ip.ipv6[15]);
+ }
+ fprintf(stdout, "Port %d\n", entry->port);
+ fprintf(stdout, "TSI %d\n", entry->tsi);
+ fprintf(stdout, "\n");
+ }
+ }
+
+ // ESGContainer
+ if (strncmp(container_filename, "", MAX_FILENAME) != 0) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "Reading ESG Container = %s\n", container_filename);
+ fprintf(stdout, "**************************************************\n\n");
+
+ read_from_file(container_filename, &buffer, &size);
+
+ struct esg_container *container = esg_container_decode((uint8_t *) buffer, size);
+ free(buffer);
+ if (container == NULL) {
+ fprintf(stderr, "ESG Container decode error\n");
+ exit(1);
+ }
+ if (container->header == NULL) {
+ fprintf(stderr, "ESG Container no header found\n");
+ exit(1);
+ }
+
+ struct esg_encapsulation_structure *fragment_management_information = NULL;
+ struct esg_data_repository *data_repository = NULL;
+ struct esg_string_repository *string_repository = NULL;
+ struct esg_container_structure *structure = NULL;
+ struct esg_init_message *init_message = NULL;
+ struct esg_textual_encoding_parameters *textual_encoding_parameters = NULL;
+ struct esg_textual_decoder_init *textual_decoder_init = NULL;
+ struct esg_namespace_prefix *namespace_prefix = NULL;
+ struct esg_xml_fragment_type *xml_fragment_type = NULL;
+ struct esg_bim_encoding_parameters *bim_encoding_parameters = NULL;
+ struct esg_bim_decoder_init *bim_decoder_init = NULL;
+ struct esg_session_partition_declaration *partition = NULL;
+ struct esg_session_field *field = NULL;
+ struct esg_session_ip_stream *ip_stream = NULL;
+ struct esg_session_ip_stream_field *ip_stream_field = NULL;
+ esg_container_header_structure_list_for_each(container->header, structure) {
+ fprintf(stdout, " structure_type %d [0x%02x]\n", structure->type, structure->type);
+ fprintf(stdout, " structure_id %d [0x%02x]\n", structure->id, structure->id);
+ fprintf(stdout, " structure_ptr %d\n", structure->ptr);
+ fprintf(stdout, " structure_length %d\n\n", structure->length);
+ switch (structure->type) {
+ case 0x01: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG Fragment Management Information\n");
+
+ fragment_management_information = (struct esg_encapsulation_structure *) structure->data;
+ if (fragment_management_information == NULL) {
+ fprintf(stderr, "ESG Fragment Management Information decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, " fragment_reference_format %d [0x%02x]\n\n", fragment_management_information->header->fragment_reference_format, fragment_management_information->header->fragment_reference_format);
+
+ struct esg_encapsulation_entry *entry;
+ esg_encapsulation_structure_entry_list_for_each(fragment_management_information, entry) {
+ fprintf(stdout, " fragment_type %d [0x%02x]\n", entry->fragment_reference->fragment_type, entry->fragment_reference->fragment_type);
+ fprintf(stdout, " data_repository_offset %d\n", entry->fragment_reference->data_repository_offset);
+ fprintf(stdout, " fragment_version %d\n", entry->fragment_version);
+ fprintf(stdout, " fragment_id %d\n\n", entry->fragment_id);
+ }
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0x02: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG String Repository / ");
+
+ string_repository = (struct esg_string_repository *) structure->data;
+ if (string_repository == NULL) {
+ fprintf(stderr, "ESG String Repository decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, "encoding_type %d / length %d\n\n", string_repository->encoding_type, string_repository->length);
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0x03: {
+ //TODO
+ break;
+ }
+ case 0x04: {
+ //TODO
+ break;
+ }
+ case 0x05: {
+ //TODO
+ break;
+ }
+ case 0xE0: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG Data Repository / ");
+
+ data_repository = (struct esg_data_repository *) structure->data;
+ if (data_repository == NULL) {
+ fprintf(stderr, "ESG Data Repository decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, "length %d\n\n", data_repository->length);
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0xE1: {
+ switch (structure->id) {
+ case 0xFF: {
+ fprintf(stdout, " ESG Session Partition Declaration\n");
+
+ partition = (struct esg_session_partition_declaration *) structure->data;
+ fprintf(stdout, " num_fields %d\n", partition->num_fields);
+ fprintf(stdout, " overlapping %d\n\n", partition->overlapping);
+ esg_session_partition_declaration_field_list_for_each(partition, field) {
+ fprintf(stdout, " identifier %d\n", field->identifier);
+ fprintf(stdout, " encoding %d\n",field->encoding);
+ fprintf(stdout, " length %d\n\n",field->length);
+ }
+ fprintf(stdout, " n_o_IPStreams %d\n", partition->n_o_ip_streams);
+ fprintf(stdout, " IPVersion6 %d\n\n", partition->ip_version_6);
+ esg_session_partition_declaration_ip_stream_list_for_each(partition, ip_stream) {
+ fprintf(stdout, " IPStreamID %d\n", ip_stream->id);
+ if (partition->ip_version_6 == 0) {
+ fprintf(stdout, " SourceIPAddress %d.%d.%d.%d\n",
+ ip_stream->source_ip.ipv4[0],
+ ip_stream->source_ip.ipv4[1],
+ ip_stream->source_ip.ipv4[2],
+ ip_stream->source_ip.ipv4[3]);
+ fprintf(stdout, " DestinationIPAddress %d.%d.%d.%d\n",
+ ip_stream->destination_ip.ipv4[0],
+ ip_stream->destination_ip.ipv4[1],
+ ip_stream->destination_ip.ipv4[2],
+ ip_stream->destination_ip.ipv4[3]);
+ } else if (partition->ip_version_6 == 1) {
+ fprintf(stdout, " SourceIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ ip_stream->source_ip.ipv6[0],
+ ip_stream->source_ip.ipv6[1],
+ ip_stream->source_ip.ipv6[2],
+ ip_stream->source_ip.ipv6[3],
+ ip_stream->source_ip.ipv6[4],
+ ip_stream->source_ip.ipv6[5],
+ ip_stream->source_ip.ipv6[6],
+ ip_stream->source_ip.ipv6[7],
+ ip_stream->source_ip.ipv6[8],
+ ip_stream->source_ip.ipv6[9],
+ ip_stream->source_ip.ipv6[10],
+ ip_stream->source_ip.ipv6[11],
+ ip_stream->source_ip.ipv6[12],
+ ip_stream->source_ip.ipv6[13],
+ ip_stream->source_ip.ipv6[14],
+ ip_stream->source_ip.ipv6[15]);
+ fprintf(stdout, " DestinationIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ ip_stream->destination_ip.ipv6[0],
+ ip_stream->destination_ip.ipv6[1],
+ ip_stream->destination_ip.ipv6[2],
+ ip_stream->destination_ip.ipv6[3],
+ ip_stream->destination_ip.ipv6[4],
+ ip_stream->destination_ip.ipv6[5],
+ ip_stream->destination_ip.ipv6[6],
+ ip_stream->destination_ip.ipv6[7],
+ ip_stream->destination_ip.ipv6[8],
+ ip_stream->destination_ip.ipv6[9],
+ ip_stream->destination_ip.ipv6[10],
+ ip_stream->destination_ip.ipv6[11],
+ ip_stream->destination_ip.ipv6[12],
+ ip_stream->destination_ip.ipv6[13],
+ ip_stream->destination_ip.ipv6[14],
+ ip_stream->destination_ip.ipv6[15]);
+ }
+ fprintf(stdout, " Port %d\n", ip_stream->port);
+ fprintf(stdout, " SessionID %d\n", ip_stream->session_id);
+
+ field = partition->field_list;
+ esg_session_ip_stream_field_list_for_each(ip_stream, ip_stream_field) {
+ switch (field->encoding) {
+ case 0x0000: {
+ if (ip_stream_field->start_field_value != NULL) {
+ fprintf(stdout, " start_field_value %s\n", ip_stream_field->start_field_value->string);
+ }
+ fprintf(stdout, " end_field_value %s\n", ip_stream_field->end_field_value->string);
+ break;
+ }
+ case 0x0101: {
+ if (ip_stream_field->start_field_value != NULL) {
+ fprintf(stdout, " start_field_value %d\n", ip_stream_field->start_field_value->unsigned_short);
+ }
+ fprintf(stdout, " end_field_value %d\n", ip_stream_field->end_field_value->unsigned_short);
+ break;
+ }
+ }
+
+ field = field->_next;
+ }
+ fprintf(stdout, "\n");
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0xE2: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG Init Message\n");
+
+ init_message = (struct esg_init_message *) structure->data;
+ if (init_message == NULL) {
+ fprintf(stderr, "ESG Init Message decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, " EncodingVersion %d [0x%02x]\n", init_message->encoding_version, init_message->encoding_version);
+ fprintf(stdout, " IndexingFlag %d\n", init_message->indexing_flag);
+ fprintf(stdout, " DecoderInitptr %d\n", init_message->decoder_init_ptr);
+ if (init_message->indexing_flag) {
+ fprintf(stdout, " IndexingVersion %d\n", init_message->indexing_version);
+ }
+
+ switch (init_message->encoding_version) {
+ case 0xF1: {
+ bim_encoding_parameters = (struct esg_bim_encoding_parameters *) init_message->encoding_parameters;
+ if (bim_encoding_parameters == NULL) {
+ fprintf(stderr, "ESG Init Message decode error / bim_encoding_parameters\n");
+ exit(1);
+ }
+ fprintf(stdout, " BufferSizeFlag %d\n", bim_encoding_parameters->buffer_size_flag);
+ fprintf(stdout, " PositionCodeFlag %d\n", bim_encoding_parameters->position_code_flag);
+ fprintf(stdout, " CharacterEncoding %d\n", bim_encoding_parameters->character_encoding);
+ if (bim_encoding_parameters->buffer_size_flag) {
+ fprintf(stdout, " BufferSize %d\n", bim_encoding_parameters->buffer_size);
+ }
+
+ // TODO BimDecoderInit
+ break;
+ }
+ case 0xF2:
+ case 0xF3: {
+ textual_encoding_parameters = (struct esg_textual_encoding_parameters *) init_message->encoding_parameters;
+ if (textual_encoding_parameters == NULL) {
+ fprintf(stderr, "ESG Init Message decode error / textual_encoding_parameters\n");
+ exit(1);
+ }
+ fprintf(stdout, " CharacterEncoding %d\n\n", textual_encoding_parameters->character_encoding);
+
+ // TextualDecoderInit
+ textual_decoder_init = (struct esg_textual_decoder_init *) init_message->decoder_init;
+ if (textual_decoder_init == NULL) {
+ fprintf(stderr, "ESG Init Message decode error / textual_decoder_init\n");
+ exit(1);
+ }
+ fprintf(stdout, " Textual DecoderInit\n");
+ fprintf(stdout, " num_namespaces_prefixes %d\n\n", textual_decoder_init->num_namespace_prefixes);
+ esg_textual_decoder_namespace_prefix_list_for_each(textual_decoder_init, namespace_prefix) {
+ fprintf(stdout, " prefix_string_ptr %d\n", namespace_prefix->prefix_string_ptr);
+ fprintf(stdout, " namespace_URI_ptr %d\n\n", namespace_prefix->namespace_uri_ptr);
+ }
+ fprintf(stdout, " num_fragment_types %d\n\n", textual_decoder_init->num_fragment_types);
+ esg_textual_decoder_xml_fragment_type_list_for_each(textual_decoder_init, xml_fragment_type) {
+ fprintf(stdout, " xpath_ptr %d\n", xml_fragment_type->xpath_ptr);
+ fprintf(stdout, " ESG_XML_fragment_type %d\n\n", xml_fragment_type->xml_fragment_type);
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown EncodingVersion\n");
+ }
+ }
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_type\n");
+ }
+ }
+ }
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, "structure_body_ptr %d\n", container->structure_body_ptr);
+ fprintf(stdout, "structure_body_length %d\n\n", container->structure_body_length);
+
+ // ESG XML Fragment
+ if (fragment_management_information) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "ESG XML Fragment\n");
+ fprintf(stdout, "**************************************************\n\n");
+
+ struct esg_encapsulation_entry *entry;
+ esg_encapsulation_structure_entry_list_for_each(fragment_management_information, entry) {
+ switch (entry->fragment_reference->fragment_type) {
+ case 0x00: {
+ if (data_repository) {
+ struct esg_encapsulated_textual_esg_xml_fragment *esg_xml_fragment = esg_encapsulated_textual_esg_xml_fragment_decode(data_repository->data + entry->fragment_reference->data_repository_offset, data_repository->length);
+
+ fprintf(stdout, "ESG_XML_fragment_type %d\n", esg_xml_fragment->esg_xml_fragment_type);
+ fprintf(stdout, "data_length %d\n", esg_xml_fragment->data_length);
+ fprintf(stdout, "fragment_version %d\n", entry->fragment_version);
+ fprintf(stdout, "fragment_id %d\n\n", entry->fragment_id);
+ char *string = (char *) malloc(esg_xml_fragment->data_length + 1);
+ memcpy(string, esg_xml_fragment->data, esg_xml_fragment->data_length);
+ string[esg_xml_fragment->data_length] = 0;
+ fprintf(stdout, "%s\n", string);
+
+ } else {
+ fprintf(stderr, "ESG Data Repository not found");
+ }
+ break;
+ }
+ case 0x01: {
+ // TODO
+ break;
+ }
+ case 0x02: {
+ // TODO
+ break;
+ }
+ default: {
+ }
+ }
+ }
+ }
+
+ // String
+ if (init_message) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "String\n");
+ fprintf(stdout, "**************************************************\n\n");
+
+ switch (init_message->encoding_version) {
+ case 0xF1: {
+ // TODO Bim
+ break;
+ }
+ case 0xF2: {
+ // TODO GZIP
+ break;
+ }
+ case 0xF3: {
+ // RAW
+ if (string_repository) {
+ textual_decoder_init = (struct esg_textual_decoder_init *) init_message->decoder_init;
+ esg_textual_decoder_namespace_prefix_list_for_each(textual_decoder_init, namespace_prefix) {
+ fprintf(stdout, "prefix_string_ptr %d\n", namespace_prefix->prefix_string_ptr);
+ fprintf(stdout, "%s\n", string_repository->data + namespace_prefix->prefix_string_ptr);
+ fprintf(stdout, "namespace_URI_ptr %d\n", namespace_prefix->namespace_uri_ptr);
+ fprintf(stdout, "%s\n\n", string_repository->data + namespace_prefix->namespace_uri_ptr - 1); // TODO -1
+ }
+
+ esg_textual_decoder_xml_fragment_type_list_for_each(textual_decoder_init, xml_fragment_type) {
+ fprintf(stdout, "xpath_ptr %d\n", xml_fragment_type->xpath_ptr);
+ fprintf(stdout, "ESG_XML_fragment_type %d\n", xml_fragment_type->xml_fragment_type);
+ fprintf(stdout, "%s\n\n", string_repository->data + xml_fragment_type->xpath_ptr - 1); // TODO -1
+ }
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown EncodingVersion\n");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/test/libucsi/Makefile b/test/libucsi/Makefile
new file mode 100644
index 0000000..1a831d0
--- /dev/null
+++ b/test/libucsi/Makefile
@@ -0,0 +1,13 @@
+# Makefile for linuxtv.org dvb-apps/test/libucsi
+
+binaries = testucsi
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbapi/libdvbapi.a ../../lib/libdvbcfg/libdvbcfg.a \
+ ../../lib/libdvbsec/libdvbsec.a ../../lib/libucsi/libucsi.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libucsi/testucsi.c b/test/libucsi/testucsi.c
new file mode 100644
index 0000000..e0a16c1
--- /dev/null
+++ b/test/libucsi/testucsi.c
@@ -0,0 +1,3528 @@
+/*
+ * section and descriptor parser test/sample application.
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/descriptor.h>
+#include <libucsi/mpeg/section.h>
+#include <libucsi/dvb/descriptor.h>
+#include <libucsi/dvb/section.h>
+#include <libucsi/atsc/descriptor.h>
+#include <libucsi/atsc/section.h>
+#include <libucsi/transport_packet.h>
+#include <libucsi/section_buf.h>
+#include <libucsi/dvb/types.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libdvbapi/dvbfe.h>
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+#include <libdvbsec/dvbsec_api.h>
+#include <libdvbsec/dvbsec_cfg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <fcntl.h>
+
+void receive_data(int dvrfd, int timeout, int data_type);
+void parse_section(uint8_t *buf, int len, int pid, int data_type);
+void parse_dvb_section(uint8_t *buf, int len, int pid, int data_type, struct section *section);
+void parse_atsc_section(uint8_t *buf, int len, int pid, int data_type, struct section *section);
+void parse_descriptor(struct descriptor *d, int indent, int data_type);
+void parse_dvb_descriptor(struct descriptor *d, int indent, int data_type);
+void parse_atsc_descriptor(struct descriptor *d, int indent, int data_type);
+void iprintf(int indent, char *fmt, ...);
+void hexdump(int indent, char *prefix, uint8_t *buf, int buflen);
+void atsctextdump(char *header, int indent, struct atsc_text *atext, int len);
+int channels_cb(struct dvbcfg_zapchannel *channel, void *private);
+void ts_from_file(char *filename, int data_type);
+
+#define TIME_CHECK_VAL 1131835761
+#define DURATION_CHECK_VAL 5643
+
+#define MAX_TUNE_TIME 3000
+#define MAX_DUMP_TIME 60
+
+#define DATA_TYPE_MPEG 0
+#define DATA_TYPE_DVB 1
+#define DATA_TYPE_ATSC 2
+
+
+struct dvbfe_handle *fe;
+struct dvbfe_info feinfo;
+int demuxfd;
+int dvrfd;
+
+int main(int argc, char *argv[])
+{
+ int adapter;
+ char *channelsfile;
+ int pidlimit = -1;
+ dvbdate_t dvbdate;
+ dvbduration_t dvbduration;
+
+ // process arguments
+ if ((argc < 3) || (argc > 4)) {
+ fprintf(stderr, "Syntax: testucsi <adapter id>|-atscfile <filename> <zapchannels file> [<pid to limit to>]\n");
+ exit(1);
+ }
+ if (!strcmp(argv[1], "-atscfile")) {
+ ts_from_file(argv[2], DATA_TYPE_ATSC);
+ exit(0);
+ }
+ adapter = atoi(argv[1]);
+ channelsfile = argv[2];
+ if (argc == 4)
+ sscanf(argv[3], "%i", &pidlimit);
+ printf("Using adapter %i\n", adapter);
+
+ // check the dvbdate conversion functions
+ unixtime_to_dvbdate(TIME_CHECK_VAL, dvbdate);
+ if (dvbdate_to_unixtime(dvbdate) != TIME_CHECK_VAL) {
+ fprintf(stderr, "XXXX dvbdate function check failed (%i!=%i)\n",
+ TIME_CHECK_VAL, (int) dvbdate_to_unixtime(dvbdate));
+ exit(1);
+ }
+ seconds_to_dvbduration(DURATION_CHECK_VAL, dvbduration);
+ if (dvbduration_to_seconds(dvbduration) != DURATION_CHECK_VAL) {
+ fprintf(stderr, "XXXX dvbduration function check failed (%i!=%i)\n",
+ DURATION_CHECK_VAL, (int) dvbduration_to_seconds(dvbduration));
+ exit(1);
+ }
+
+ // open the frontend
+ if ((fe = dvbfe_open(adapter, 0, 0)) == NULL) {
+ perror("open frontend");
+ exit(1);
+ }
+ dvbfe_get_info(fe, 0, &feinfo, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
+ int data_type = DATA_TYPE_MPEG;
+ switch(feinfo.type) {
+ case DVBFE_TYPE_DVBS:
+ case DVBFE_TYPE_DVBC:
+ case DVBFE_TYPE_DVBT:
+ data_type = DATA_TYPE_DVB;
+ break;
+
+ case DVBFE_TYPE_ATSC:
+ data_type = DATA_TYPE_ATSC;
+ break;
+ }
+
+ // open demux devices
+ if ((demuxfd = dvbdemux_open_demux(adapter, 0, 0)) < 0) {
+ perror("demux");
+ exit(1);
+ }
+ if ((dvrfd = dvbdemux_open_dvr(adapter, 0, 1, 1)) < 0) {
+ perror("dvr");
+ exit(1);
+ }
+
+ // make the demux buffer a bit larger
+ if (dvbdemux_set_buffer(demuxfd, 1024*1024)) {
+ perror("set buffer");
+ exit(1);
+ }
+
+ // setup filter to capture stuff
+ if (dvbdemux_set_pid_filter(demuxfd, pidlimit, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DVR, 1)) {
+ perror("set pid filter");
+ exit(1);
+ }
+
+ // process all the channels
+ FILE *channels = fopen(channelsfile, "r");
+ if (channels == NULL) {
+ fprintf(stderr, "Unable to open %s\n", channelsfile);
+ exit(1);
+ }
+ dvbcfg_zapchannel_parse(channels, channels_cb, (void*) (long) data_type);
+ return 0;
+}
+
+void ts_from_file(char *filename, int data_type) {
+ int fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open file %s\n", filename);
+ exit(1);
+ }
+ receive_data(fd, 1000000000, data_type);
+}
+
+int channels_cb(struct dvbcfg_zapchannel *channel, void *private)
+{
+ long data_type = (long) private;
+ struct dvbsec_config sec;
+
+ if (dvbsec_cfg_find(NULL, "UNIVERSAL", &sec)) {
+ fprintf(stderr, "Unable to find SEC id\n");
+ exit(1);
+ }
+
+ if (dvbsec_set(fe,
+ &sec,
+ channel->polarization,
+ DISEQC_SWITCH_UNCHANGED,
+ DISEQC_SWITCH_UNCHANGED,
+ &channel->fe_params,
+ MAX_TUNE_TIME)) {
+ fprintf(stderr, "Failed to lock!\n");
+ } else {
+ printf("Tuned successfully!\n");
+ receive_data(dvrfd, MAX_DUMP_TIME, data_type);
+ }
+
+ return 0;
+}
+
+void receive_data(int _dvrfd, int timeout, int data_type)
+{
+ unsigned char databuf[TRANSPORT_PACKET_LENGTH*20];
+ int sz;
+ int pid;
+ int i;
+ int used;
+ int section_status;
+ time_t starttime;
+ unsigned char continuities[TRANSPORT_MAX_PIDS];
+ struct section_buf *section_bufs[TRANSPORT_MAX_PIDS];
+ struct transport_packet *tspkt;
+ struct transport_values tsvals;
+
+ // process the data
+ starttime = time(NULL);
+ memset(continuities, 0, sizeof(continuities));
+ memset(section_bufs, 0, sizeof(section_bufs));
+ while((time(NULL) - starttime) < timeout) {
+ // got some!
+ if ((sz = read(_dvrfd, databuf, sizeof(databuf))) < 0) {
+ if (errno == EOVERFLOW) {
+ fprintf(stderr, "data overflow!\n");
+ continue;
+ } else if (errno == EAGAIN) {
+ usleep(100);
+ continue;
+ } else {
+ perror("read error");
+ exit(1);
+ }
+ }
+ for(i=0; i < sz; i+=TRANSPORT_PACKET_LENGTH) {
+ // parse the transport packet
+ tspkt = transport_packet_init(databuf + i);
+ if (tspkt == NULL) {
+ fprintf(stderr, "XXXX Bad sync byte\n");
+ continue;
+ }
+ pid = transport_packet_pid(tspkt);
+
+ // extract all TS packet values even though we don't need them (to check for
+ // library segfaults etc)
+ if (transport_packet_values_extract(tspkt, &tsvals, 0xffff) < 0) {
+ fprintf(stderr, "XXXX Bad packet received (pid:%04x)\n", pid);
+ continue;
+ }
+
+ // check continuity
+ if (transport_packet_continuity_check(tspkt,
+ tsvals.flags & transport_adaptation_flag_discontinuity,
+ continuities + pid)) {
+ fprintf(stderr, "XXXX Continuity error (pid:%04x)\n", pid);
+ continuities[pid] = 0;
+ if (section_bufs[pid] != NULL) {
+ section_buf_reset(section_bufs[pid]);
+ }
+ continue;
+ }
+
+ // allocate section buf if we don't have one already
+ if (section_bufs[pid] == NULL) {
+ section_bufs[pid] = (struct section_buf*)
+ malloc(sizeof(struct section_buf) + DVB_MAX_SECTION_BYTES);
+ if (section_bufs[pid] == NULL) {
+ fprintf(stderr, "Failed to allocate section buf (pid:%04x)\n", pid);
+ exit(1);
+ }
+ section_buf_init(section_bufs[pid], DVB_MAX_SECTION_BYTES);
+ }
+
+ // process the payload data as a section
+ while(tsvals.payload_length) {
+ used = section_buf_add_transport_payload(section_bufs[pid],
+ tsvals.payload,
+ tsvals.payload_length,
+ tspkt->payload_unit_start_indicator,
+ &section_status);
+ tspkt->payload_unit_start_indicator = 0;
+ tsvals.payload_length -= used;
+ tsvals.payload += used;
+
+ if (section_status == 1) {
+ parse_section(section_buf_data(section_bufs[pid]),
+ section_bufs[pid]->len, pid, data_type);
+ section_buf_reset(section_bufs[pid]);
+ } else if (section_status < 0) {
+ // some kind of error - just discard
+ fprintf(stderr, "XXXX bad section %04x %i\n",pid, section_status);
+ section_buf_reset(section_bufs[pid]);
+ }
+ }
+ }
+ }
+}
+
+void parse_section(uint8_t *buf, int len, int pid, int data_type)
+{
+ struct section *section;
+ struct section_ext *section_ext = NULL;
+
+ if ((section = section_codec(buf, len)) == NULL) {
+ return;
+ }
+
+ switch(section->table_id) {
+ case stag_mpeg_program_association:
+ {
+ struct mpeg_pat_section *pat;
+ struct mpeg_pat_program *cur;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode PAT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((pat = mpeg_pat_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX PAT section decode error\n");
+ return;
+ }
+ printf("SCT transport_stream_id:0x%04x\n", mpeg_pat_section_transport_stream_id(pat));
+ mpeg_pat_section_programs_for_each(pat, cur) {
+ printf("\tSCT program_number:0x%04x pid:0x%04x\n", cur->program_number, cur->pid);
+ }
+ break;
+ }
+
+ case stag_mpeg_conditional_access:
+ {
+ struct mpeg_cat_section *cat;
+ struct descriptor *curd;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode CAT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((cat = mpeg_cat_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX CAT section decode error\n");
+ return;
+ }
+ mpeg_cat_section_descriptors_for_each(cat, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_mpeg_program_map:
+ {
+ struct mpeg_pmt_section *pmt;
+ struct descriptor *curd;
+ struct mpeg_pmt_stream *cur_stream;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode PMT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((pmt = mpeg_pmt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX PMT section decode error\n");
+ return;
+ }
+ printf("SCT program_number:0x%04x pcr_pid:0x%02x\n", mpeg_pmt_section_program_number(pmt), pmt->pcr_pid);
+ mpeg_pmt_section_descriptors_for_each(pmt, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
+ printf("\tSCT stream_type:0x%02x pid:0x%04x\n", cur_stream->stream_type, cur_stream->pid);
+ mpeg_pmt_stream_descriptors_for_each(cur_stream, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_mpeg_transport_stream_description:
+ {
+ struct mpeg_tsdt_section *tsdt;
+ struct descriptor *curd;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode TSDT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tsdt = mpeg_tsdt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX TSDT section decode error\n");
+ return;
+ }
+ mpeg_tsdt_section_descriptors_for_each(tsdt, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_mpeg_metadata:
+ {
+ struct mpeg_metadata_section *metadata;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode metadata (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((metadata = mpeg_metadata_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX metadata section decode error\n");
+ return;
+ }
+ printf("SCT random_access_indicator:%i decoder_config_flag:%i fragment_indicator:%i service_id:%02x\n",
+ mpeg_metadata_section_random_access_indicator(metadata),
+ mpeg_metadata_section_decoder_config_flag(metadata),
+ mpeg_metadata_section_fragment_indicator(metadata),
+ mpeg_metadata_section_service_id(metadata));
+ hexdump(0, "SCT ", mpeg_metadata_section_data(metadata), mpeg_metadata_section_data_length(metadata));
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_mpeg_iso14496_scene_description:
+ case stag_mpeg_iso14496_object_description:
+ {
+ struct mpeg_odsmt_section *odsmt;
+ struct mpeg_odsmt_stream *cur_stream;
+ struct descriptor *curd;
+ int _index;
+ uint8_t *objects;
+ size_t objects_length;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode ISO14496 (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((odsmt = mpeg_odsmt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX ISO14496 section decode error\n");
+ return;
+ }
+ printf("SCT PID:0x%04x\n", mpeg_odsmt_section_pid(odsmt));
+ mpeg_odsmt_section_streams_for_each(osdmt, cur_stream, _index) {
+ if (odsmt->stream_count == 0) {
+ printf("\tSCT SINGLE 0x%04x\n", cur_stream->u.single.esid);
+ } else {
+ printf("\tSCT MULTI 0x%04x 0x%02x\n", cur_stream->u.multi.esid, cur_stream->u.multi.fmc);
+ }
+ mpeg_odsmt_stream_descriptors_for_each(osdmt, cur_stream, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ objects = mpeg_odsmt_section_object_descriptors(odsmt, &objects_length);
+ if (objects == NULL) {
+ printf("SCT XXXX OSDMT parse error\n");
+ break;
+ }
+ hexdump(1, "SCT ", objects, objects_length);
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ default:
+ switch(data_type) {
+ case DATA_TYPE_DVB:
+ parse_dvb_section(buf, len, pid, data_type, section);
+ break;
+
+ case DATA_TYPE_ATSC:
+ parse_atsc_section(buf, len, pid, data_type, section);
+ break;
+
+ default:
+ fprintf(stderr, "SCT XXXX Unknown table_id:0x%02x (pid:0x%04x)\n",
+ section->table_id, pid);
+// hexdump(0, "SCT ", buf, len);
+ return;
+ }
+ }
+
+ printf("\n");
+}
+
+void parse_dvb_section(uint8_t *buf, int len, int pid, int data_type, struct section *section)
+{
+ struct section_ext *section_ext = NULL;
+
+ switch(section->table_id) {
+ case stag_dvb_network_information_actual:
+ case stag_dvb_network_information_other:
+ {
+ struct dvb_nit_section *nit;
+ struct descriptor *curd;
+ struct dvb_nit_section_part2 *part2;
+ struct dvb_nit_transport *cur_transport;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode NIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((nit = dvb_nit_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX NIT section decode error\n");
+ return;
+ }
+ printf("SCT network_id:0x%04x\n", dvb_nit_section_network_id(nit));
+ dvb_nit_section_descriptors_for_each(nit, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ part2 = dvb_nit_section_part2(nit);
+ dvb_nit_section_transports_for_each(nit, part2, cur_transport) {
+ printf("\tSCT transport_stream_id:0x%04x original_network_id:0x%04x\n", cur_transport->transport_stream_id, cur_transport->original_network_id);
+ dvb_nit_transport_descriptors_for_each(cur_transport, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_service_description_actual:
+ case stag_dvb_service_description_other:
+ {
+ struct dvb_sdt_section *sdt;
+ struct dvb_sdt_service *cur_service;
+ struct descriptor *curd;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode SDT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((sdt = dvb_sdt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX SDT section decode error\n");
+ return;
+ }
+ printf("SCT transport_stream_id:0x%04x original_network_id:0x%04x\n", dvb_sdt_section_transport_stream_id(sdt), sdt->original_network_id);
+ dvb_sdt_section_services_for_each(sdt, cur_service) {
+ printf("\tSCT service_id:0x%04x eit_schedule_flag:%i eit_present_following_flag:%i running_status:%i free_ca_mode:%i\n",
+ cur_service->service_id,
+ cur_service->eit_schedule_flag,
+ cur_service->eit_present_following_flag,
+ cur_service->running_status,
+ cur_service->free_ca_mode);
+ dvb_sdt_service_descriptors_for_each(cur_service, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_bouquet_association:
+ {
+ struct dvb_bat_section *bat;
+ struct descriptor *curd;
+ struct dvb_bat_section_part2 *part2;
+ struct dvb_bat_transport *cur_transport;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode BAT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((bat = dvb_bat_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX BAT section decode error\n");
+ return;
+ }
+ printf("SCT bouquet_id:0x%04x\n", dvb_bat_section_bouquet_id(bat));
+ dvb_bat_section_descriptors_for_each(bat, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ part2 = dvb_bat_section_part2(bat);
+ dvb_bat_section_transports_for_each(part2, cur_transport) {
+ printf("\tSCT transport_stream_id:0x%04x original_network_id:0x%04x\n",
+ cur_transport->transport_stream_id,
+ cur_transport->original_network_id);
+ dvb_bat_transport_descriptors_for_each(cur_transport, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_update_notification:
+ case stag_dvb_ip_mac_notification:
+ {
+ struct dvb_int_section *_int;
+ struct descriptor *curd;
+ struct dvb_int_target *cur_target;
+ struct dvb_int_operational_loop *operational_loop;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode INT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((_int = dvb_int_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX INT section decode error\n");
+ return;
+ }
+ printf("SCT action_type:0x%02x platform_id_hash:0x%02x platform_id:0x%06x processing_order:0x%02x\n",
+ dvb_int_section_action_type(_int),
+ dvb_int_section_platform_id_hash(_int),
+ _int->platform_id,
+ _int->processing_order);
+ dvb_int_section_platform_descriptors_for_each(_int, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ dvb_int_section_target_loop_for_each(_int, cur_target) {
+ dvb_int_target_target_descriptors_for_each(cur_target, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ operational_loop = dvb_int_target_operational_loop(cur_target);
+ dvb_int_operational_loop_operational_descriptors_for_each(operational_loop, curd) {
+ parse_descriptor(curd, 3, data_type);
+ }
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_dvb_event_information_nownext_actual:
+ case stag_dvb_event_information_nownext_other:
+ case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+ case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
+ {
+ struct dvb_eit_section *eit;
+ struct dvb_eit_event *cur_event;
+ struct descriptor *curd;
+ time_t start_time;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode EIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((eit = dvb_eit_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX EIT section decode error\n");
+ return;
+ }
+ printf("SCT service_id:0x%04x transport_stream_id:0x%04x original_network_id:0x%04x segment_last_section_number:0x%02x last_table_id:0x%02x\n",
+ dvb_eit_section_service_id(eit),
+ eit->transport_stream_id,
+ eit->original_network_id,
+ eit->segment_last_section_number,
+ eit->last_table_id);
+ dvb_eit_section_events_for_each(eit, cur_event) {
+ start_time = dvbdate_to_unixtime(cur_event->start_time);
+ printf("\tSCT event_id:0x%04x duration:%i running_status:%i free_ca_mode:%i start_time:%i -- %s",
+ cur_event->event_id,
+ dvbduration_to_seconds(cur_event->duration),
+ cur_event->running_status,
+ cur_event->free_ca_mode,
+ (int) start_time,
+ ctime(&start_time));
+ dvb_eit_event_descriptors_for_each(cur_event, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_time_date:
+ {
+ struct dvb_tdt_section *tdt;
+ time_t dvbtime;
+
+ printf("SCT Decode TDT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tdt = dvb_tdt_section_codec(section)) == NULL) {
+ fprintf(stderr, "XXXX TDT section decode error\n");
+ return;
+ }
+ dvbtime = dvbdate_to_unixtime(tdt->utc_time);
+ printf("SCT Time: %i -- %s", (int) dvbtime, ctime(&dvbtime));
+ break;
+ }
+
+ case stag_dvb_running_status:
+ {
+ struct dvb_rst_section *rst;
+ struct dvb_rst_status *cur_status;
+
+ printf("SCT Decode RST (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((rst = dvb_rst_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX RST section decode error\n");
+ return;
+ }
+ dvb_rst_section_statuses_for_each(rst, cur_status) {
+ printf("\tSCT transport_stream_id:0x%04x original_network_id:0x%04x service_id:0x%04x event_id:0x%04x running_status:%i\n",
+ cur_status->transport_stream_id,
+ cur_status->original_network_id,
+ cur_status->service_id,
+ cur_status->event_id,
+ cur_status->running_status);
+ }
+
+// hexdump(0, "SCT ", buf, len);
+// getchar();
+ break;
+ }
+
+ case stag_dvb_stuffing:
+ {
+ struct dvb_st_section *st;
+
+ printf("SCT Decode ST (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((st = dvb_st_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX ST section decode error\n");
+ return;
+ }
+ printf("SCT Length: %i\n", dvb_st_section_data_length(st));
+ break;
+ }
+
+ case stag_dvb_time_offset:
+ {
+ struct dvb_tot_section *tot;
+ struct descriptor *curd;
+ time_t dvbtime;
+
+ if (section_check_crc(section))
+ return;
+ printf("SCT Decode TOT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tot = dvb_tot_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX TOT section decode error\n");
+ return;
+ }
+ dvbtime = dvbdate_to_unixtime(tot->utc_time);
+ printf("SCT utc_time: %i -- %s", (int) dvbtime, ctime(&dvbtime));
+ dvb_tot_section_descriptors_for_each(tot, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_dvb_tva_container:
+ {
+ struct dvb_tva_container_section *tva;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode tva (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tva = dvb_tva_container_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX tva section decode error\n");
+ return;
+ }
+ printf("SCT container_id:%04x\n",
+ dvb_tva_container_section_container_id(tva));
+ hexdump(0, "SCT ", dvb_tva_container_section_data(tva), dvb_tva_container_section_data_length(tva));
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_dvb_discontinuity_information:
+ {
+ struct dvb_dit_section *dit;
+
+ printf("SCT Decode DIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((dit = dvb_dit_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX DIT section decode error\n");
+ return;
+ }
+ printf("SCT transition_flag:%i\n", dit->transition_flag);
+
+// hexdump(0, "SCT ", buf, len);
+// getchar();
+ break;
+ }
+
+ case stag_dvb_selection_information:
+ {
+ struct dvb_sit_section *sit;
+ struct descriptor *curd;
+ struct dvb_sit_service *cur_service;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode SIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((sit = dvb_sit_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX SIT section decode error\n");
+ return;
+ }
+ dvb_sit_section_descriptors_for_each(sit, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ dvb_sit_section_services_for_each(sit, cur_service) {
+ printf("\tSCT service_id:0x%04x running_status:%i\n", cur_service->service_id, cur_service->running_status);
+ dvb_sit_service_descriptors_for_each(cur_service, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ default:
+ fprintf(stderr, "SCT XXXX Unknown table_id:0x%02x (pid:0x%04x)\n", section->table_id, pid);
+// hexdump(0, "SCT ", buf, len);
+ return;
+ }
+}
+
+void parse_atsc_section(uint8_t *buf, int len, int pid, int data_type, struct section *section)
+{
+ struct section_ext *section_ext = NULL;
+ struct atsc_section_psip *section_psip = NULL;
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ if ((section_psip = atsc_section_psip_decode(section_ext)) == NULL) {
+ return;
+ }
+
+ printf("SCT protocol_version:%i\n", section_psip->protocol_version);
+
+ switch(section->table_id) {
+ case stag_atsc_master_guide:
+ {
+ struct atsc_mgt_section *mgt;
+ struct atsc_mgt_table *cur_table;
+ struct atsc_mgt_section_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode MGT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((mgt = atsc_mgt_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX MGT section decode error\n");
+ return;
+ }
+ atsc_mgt_section_tables_for_each(mgt, cur_table, idx) {
+ printf("\tSCT table_type:0x%04x table_type_PID:%04x table_type_version_number:%i number_bytes:%i\n",
+ cur_table->table_type,
+ cur_table->table_type_PID,
+ cur_table->table_type_version_number,
+ cur_table->number_bytes);
+ atsc_mgt_table_descriptors_for_each(cur_table, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ part2 = atsc_mgt_section_part2(mgt);
+ atsc_mgt_section_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_atsc_terrestrial_virtual_channel:
+ {
+ struct atsc_tvct_section *tvct;
+ struct atsc_tvct_channel *cur_channel;
+ struct atsc_tvct_section_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode TVCT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tvct = atsc_tvct_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX TVCT section decode error\n");
+ return;
+ }
+ printf("\tSCT tranport_stream_id:0x%04x\n",
+ atsc_tvct_section_transport_stream_id(tvct));
+
+ atsc_tvct_section_channels_for_each(tvct, cur_channel, idx) {
+ hexdump(0, "SCT short_name ", (uint8_t*) cur_channel->short_name, 7*2);
+
+ printf("\tSCT major_channel_number:%04x minor_channel_number:%04x modulation_mode:%02x carrier_frequency:%i channel_TSID:%04x program_number:%04x ETM_location:%i access_controlled:%i hidden:%i hide_guide:%i service_type:%02x source_id:%04x\n",
+ cur_channel->major_channel_number,
+ cur_channel->minor_channel_number,
+ cur_channel->modulation_mode,
+ cur_channel->carrier_frequency,
+ cur_channel->channel_TSID,
+ cur_channel->program_number,
+ cur_channel->ETM_location,
+ cur_channel->access_controlled,
+ cur_channel->hidden,
+ cur_channel->hide_guide,
+ cur_channel->service_type,
+ cur_channel->source_id);
+ atsc_tvct_channel_descriptors_for_each(cur_channel, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ part2 = atsc_tvct_section_part2(tvct);
+ atsc_tvct_section_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_atsc_cable_virtual_channel:
+ {
+ struct atsc_cvct_section *cvct;
+ struct atsc_cvct_channel *cur_channel;
+ struct atsc_cvct_section_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode CVCT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((cvct = atsc_cvct_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX CVCT section decode error\n");
+ return;
+ }
+ printf("\tSCT tranport_stream_id:0x%04x\n",
+ atsc_cvct_section_transport_stream_id(cvct));
+
+ atsc_cvct_section_channels_for_each(cvct, cur_channel, idx) {
+ hexdump(0, "SCT short_name ", (uint8_t*) cur_channel->short_name, 7*2);
+
+ printf("\tSCT major_channel_number:%04x minor_channel_number:%04x modulation_mode:%02x carrier_frequency:%i channel_TSID:%04x program_number:%04x ETM_location:%i access_controlled:%i hidden:%i path_select:%i out_of_band:%i hide_guide:%i service_type:%02x source_id:%04x\n",
+ cur_channel->major_channel_number,
+ cur_channel->minor_channel_number,
+ cur_channel->modulation_mode,
+ cur_channel->carrier_frequency,
+ cur_channel->channel_TSID,
+ cur_channel->program_number,
+ cur_channel->ETM_location,
+ cur_channel->access_controlled,
+ cur_channel->hidden,
+ cur_channel->path_select,
+ cur_channel->out_of_band,
+ cur_channel->hide_guide,
+ cur_channel->service_type,
+ cur_channel->source_id);
+ atsc_cvct_channel_descriptors_for_each(cur_channel, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ part2 = atsc_cvct_section_part2(cvct);
+ atsc_cvct_section_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_atsc_rating_region:
+ {
+ struct atsc_rrt_section *rrt;
+ struct atsc_rrt_section_part2 *part2;
+ struct atsc_rrt_dimension *cur_dimension;
+ struct atsc_rrt_dimension_part2 *dpart2;
+ struct atsc_rrt_dimension_value *cur_value;
+ struct atsc_rrt_dimension_value_part2 *vpart2;
+ struct atsc_rrt_section_part3 *part3;
+ struct descriptor *curd;
+ int didx;
+ int vidx;
+
+ printf("SCT Decode RRT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((rrt = atsc_rrt_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX RRT section decode error\n");
+ return;
+ }
+ printf("\tSCT rating_region:0x%02x\n",
+ atsc_rrt_section_rating_region(rrt));
+ atsctextdump("SCT region_name:", 1,
+ atsc_rrt_section_rating_region_name_text(rrt),
+ rrt->rating_region_name_length);
+
+ part2 = atsc_rrt_section_part2(rrt);
+ atsc_rrt_section_dimensions_for_each(part2, cur_dimension, didx) {
+ atsctextdump("SCT dimension_name:", 2,
+ atsc_rrt_dimension_name_text(cur_dimension),
+ cur_dimension->dimension_name_length);
+
+ dpart2 = atsc_rrt_dimension_part2(cur_dimension);
+ printf("\tSCT graduated_scale:%i\n",
+ dpart2->graduated_scale);
+
+ atsc_rrt_dimension_part2_values_for_each(dpart2, cur_value, vidx) {
+ atsctextdump("SCT value_abbrev_name:", 3,
+ atsc_rrt_dimension_value_abbrev_rating_value_text(cur_value),
+ cur_value->abbrev_rating_value_length);
+
+ vpart2 = atsc_rrt_dimension_value_part2(cur_value);
+ atsctextdump("SCT value_text:", 3,
+ atsc_rrt_dimension_value_part2_rating_value_text(vpart2),
+ vpart2->rating_value_length);
+ }
+ }
+
+ part3 = atsc_rrt_section_part3(part2);
+ atsc_rrt_section_part3_descriptors_for_each(part3, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_atsc_event_information:
+ {
+ struct atsc_eit_section *eit;
+ struct atsc_eit_event *cur_event;
+ struct atsc_eit_event_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode EIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((eit = atsc_eit_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX EIT section decode error\n");
+ return;
+ }
+ printf("\tSCT source_id:0x%04x\n",
+ atsc_eit_section_source_id(eit));
+
+ atsc_eit_section_events_for_each(eit, cur_event, idx) {
+ printf("\t\tSCT event_id:%04x start_time:%i ETM_location:%i length_in_secs:%i\n",
+ cur_event->event_id,
+ cur_event->start_time,
+ cur_event->ETM_location,
+ cur_event->length_in_seconds);
+
+ atsctextdump("SCT title:", 2,
+ atsc_eit_event_name_title_text(cur_event),
+ cur_event->title_length);
+
+ part2 = atsc_eit_event_part2(cur_event);
+
+ atsc_eit_event_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_atsc_extended_text:
+ {
+ struct atsc_ett_section *ett;
+
+ printf("SCT Decode ETT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((ett = atsc_ett_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX ETT section decode error\n");
+ return;
+ }
+ printf("\tSCT ETM_source_id:0x%04x ETM_sub_id:%04x ETM_type:%02x\n",
+ ett->ETM_source_id,
+ ett->ETM_sub_id,
+ ett->ETM_type);
+ atsctextdump("SCT text:", 1,
+ atsc_ett_section_extended_text_message(ett),
+ atsc_ett_section_extended_text_message_length(ett));
+ break;
+ }
+
+ case stag_atsc_system_time:
+ {
+ struct atsc_stt_section *stt;
+ struct descriptor *curd;
+
+ printf("SCT Decode STT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((stt = atsc_stt_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX STT section decode error\n");
+ return;
+ }
+ printf("\tSCT system_time:%i gps_utc_offset:%i DS_status:%i DS_day_of_month:%i DS_hour:%i\n",
+ stt->system_time,
+ stt->gps_utc_offset,
+ stt->DS_status,
+ stt->DS_day_of_month,
+ stt->DS_hour);
+ atsc_stt_section_descriptors_for_each(stt, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ break;
+ }
+
+ default:
+ fprintf(stderr, "SCT XXXX Unknown table_id:0x%02x (pid:0x%04x)\n", section->table_id, pid);
+ hexdump(0, "SCT ", buf, len);
+ return;
+ }
+}
+
+void parse_descriptor(struct descriptor *d, int indent, int data_type)
+{
+ switch(d->tag) {
+ case dtag_mpeg_video_stream:
+ {
+ struct mpeg_video_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_video_stream_descriptor\n");
+ dx = mpeg_video_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_video_stream_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC multiple_frame_rate_flag:%i frame_rate_code:%i mpeg_1_only_flag:%i constrained_parameter_flag:%i still_picture_flag:%i\n",
+ dx->multiple_frame_rate_flag,
+ dx->frame_rate_code,
+ dx->mpeg_1_only_flag,
+ dx->constrained_parameter_flag,
+ dx->still_picture_flag);
+ if (!dx->mpeg_1_only_flag) {
+ struct mpeg_video_stream_extra *extra = mpeg_video_stream_descriptor_extra(dx);
+ iprintf(indent, "DSC profile_and_level_indication:0x%02x chroma_format:%i frame_rate_extension:%i\n",
+ extra->profile_and_level_indication,
+ extra->chroma_format,
+ extra->frame_rate_extension);
+ }
+ break;
+ }
+
+ case dtag_mpeg_audio_stream:
+ {
+ struct mpeg_audio_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_audio_stream_descriptor\n");
+ dx = mpeg_audio_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_audio_stream_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC free_format_flag:%i id:%i layer:%i variable_rate_audio_indicator:%i\n",
+ dx->free_format_flag,
+ dx->id,
+ dx->layer,
+ dx->variable_rate_audio_indicator);
+ break;
+ }
+
+ case dtag_mpeg_hierarchy:
+ {
+ struct mpeg_hierarchy_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_hierarchy_descriptor\n");
+ dx = mpeg_hierarchy_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_hierarchy_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC hierarchy_type:%i hierarchy_layer_index:%i hierarchy_embedded_layer_index:%i hierarchy_channel:%i\n",
+ dx->hierarchy_type,
+ dx->hierarchy_layer_index,
+ dx->hierarchy_embedded_layer_index,
+ dx->hierarchy_channel);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_registration:
+ {
+ struct mpeg_registration_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_registration_descriptor\n");
+ dx = mpeg_registration_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_registration_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC format_identifier:0x%x\n",
+ dx->format_identifier);
+ iprintf(indent, "DSC additional_id_info:\n");
+ hexdump(indent, "DSC ",
+ mpeg_registration_descriptor_additional_id_info(dx),
+ mpeg_registration_descriptor_additional_id_info_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_data_stream_alignment:
+ {
+ struct mpeg_data_stream_alignment_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_data_stream_alignment_descriptor\n");
+ dx = mpeg_data_stream_alignment_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_data_stream_alignment_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC alignment_type:%i\n",
+ dx->alignment_type);
+ break;
+ }
+
+ case dtag_mpeg_target_background_grid:
+ {
+ struct mpeg_target_background_grid_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_target_background_grid_descriptor\n");
+ dx = mpeg_target_background_grid_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_target_background_grid_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC horizontal_size:%i vertical_size:%i aspect_ratio_information:%i\n",
+ dx->horizontal_size,
+ dx->vertical_size,
+ dx->aspect_ratio_information);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_video_window:
+ {
+ struct mpeg_video_window_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_video_window_descriptor\n");
+ dx = mpeg_video_window_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_video_window_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC horizontal_offset:%i vertical_offset:%i window_priority:%i\n",
+ dx->horizontal_offset,
+ dx->vertical_offset,
+ dx->window_priority);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_ca:
+ {
+ struct mpeg_ca_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_ca_descriptor\n");
+ dx = mpeg_ca_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_ca_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC ca_system_id:0x%04x ca_pid:0x%04x\n",
+ dx->ca_system_id,
+ dx->ca_pid);
+ iprintf(indent, "DSC data:\n");
+ hexdump(indent, "DSC ", mpeg_ca_descriptor_data(dx), mpeg_ca_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_iso_639_language:
+ {
+ struct mpeg_iso_639_language_descriptor *dx;
+ struct mpeg_iso_639_language_code *cur_lang;
+
+ iprintf(indent, "DSC Decode mpeg_iso_639_language_descriptor\n");
+ dx = mpeg_iso_639_language_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_iso_639_language_descriptor decode error\n");
+ return;
+ }
+ mpeg_iso_639_language_descriptor_languages_for_each(dx, cur_lang) {
+ iprintf(indent+1, "DSC language_code:%.3s audio_type:0x%02x\n",
+ cur_lang->language_code,
+ cur_lang->audio_type);
+ }
+ break;
+ }
+
+ case dtag_mpeg_system_clock:
+ {
+ struct mpeg_system_clock_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_system_clock_descriptor\n");
+ dx = mpeg_system_clock_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_system_clock_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC external_clock_reference_indicator:%i clock_accuracy_integer:%i clock_accuracy_exponent:%i\n",
+ dx->external_clock_reference_indicator,
+ dx->clock_accuracy_integer,
+ dx->clock_accuracy_exponent);
+ break;
+ }
+
+ case dtag_mpeg_multiplex_buffer_utilization:
+ {
+ struct mpeg_multiplex_buffer_utilization_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_multiplex_buffer_utilization_descriptor\n");
+ dx = mpeg_multiplex_buffer_utilization_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_multiplex_buffer_utilization_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC bound_valid_flag:%i ltw_offset_lower_bound:%i ltw_offset_upper_bound:%i\n",
+ dx->bound_valid_flag,
+ dx->ltw_offset_lower_bound,
+ dx->ltw_offset_upper_bound);
+ break;
+ }
+
+ case dtag_mpeg_copyright:
+ {
+ struct mpeg_copyright_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_copyright_descriptor\n");
+ dx = mpeg_copyright_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_copyright_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC copyright_identifier:0x%08x\n",
+ dx->copyright_identifier);
+ iprintf(indent, "DSC data:\n");
+ hexdump(indent, "DSC ", mpeg_copyright_descriptor_data(dx), mpeg_copyright_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_maximum_bitrate:
+ {
+ struct mpeg_maximum_bitrate_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_maximum_bitrate_descriptor\n");
+ dx = mpeg_maximum_bitrate_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_maximum_bitrate_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC maximum_bitrate:%i\n",
+ dx->maximum_bitrate);
+ break;
+ }
+
+ case dtag_mpeg_private_data_indicator:
+ {
+ struct mpeg_private_data_indicator_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_private_data_indicator_descriptor\n");
+ dx = mpeg_private_data_indicator_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_private_data_indicator_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC private_data_indicator:0x%x\n",
+ dx->private_data_indicator);
+ break;
+ }
+
+ case dtag_mpeg_smoothing_buffer:
+ {
+ struct mpeg_smoothing_buffer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_smoothing_buffer_descriptor\n");
+ dx = mpeg_smoothing_buffer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_smoothing_buffer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC sb_leak_rate:%i sb_size:%i\n",
+ dx->sb_leak_rate,
+ dx->sb_size);
+ break;
+ }
+
+ case dtag_mpeg_std:
+ {
+ struct mpeg_std_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_std_descriptor\n");
+ dx = mpeg_std_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_std_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC leak_valid_flag:%i\n",
+ dx->leak_valid_flag);
+ break;
+ }
+
+ case dtag_mpeg_ibp:
+ {
+ struct mpeg_ibp_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_ibp_descriptor\n");
+ dx = mpeg_ibp_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_ibp_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC closed_gop_flag:%i identical_gop_flag:%i max_gop_length:%i\n",
+ dx->closed_gop_flag, dx->identical_gop_flag, dx->max_gop_length);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_4_video:
+ {
+ struct mpeg4_video_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg4_video_descriptor\n");
+ dx = mpeg4_video_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg4_video_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mpeg4_visual_profile_and_level:0x%02x\n",
+ dx->mpeg4_visual_profile_and_level);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_4_audio:
+ {
+ struct mpeg4_audio_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg4_audio_descriptor\n");
+ dx = mpeg4_audio_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg4_audio_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mpeg4_audio_profile_and_level:0x%02x\n",
+ dx->mpeg4_audio_profile_and_level);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_iod:
+ {
+ struct mpeg_iod_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_iod_descriptor\n");
+ dx = mpeg_iod_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_iod_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC scope_of_iod_label:0x%08x iod_label:0x%02x\n",
+ dx->scope_of_iod_label, dx->iod_label);
+ iprintf(indent, "DSC iod:\n");
+ hexdump(indent, "DSC ", mpeg_iod_descriptor_iod(dx), mpeg_iod_descriptor_iod_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_sl:
+ {
+ struct mpeg_sl_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_sl_descriptor\n");
+ dx = mpeg_sl_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_sl_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC es_id:0x%04x\n",
+ dx->es_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_fmc:
+ {
+ struct mpeg_fmc_descriptor *dx;
+ struct mpeg_flex_mux *cur_fm;
+
+ iprintf(indent, "DSC Decode mpeg_fmc_descriptor\n");
+ dx = mpeg_fmc_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_fmc_descriptor_descriptor decode error\n");
+ return;
+ }
+ mpeg_fmc_descriptor_muxes_for_each(dx, cur_fm) {
+ iprintf(indent+1, "DSC es_id:0x%04x flex_mux_channel:0x%02x\n",
+ cur_fm->es_id,
+ cur_fm->flex_mux_channel);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_external_es_id:
+ {
+ struct mpeg_external_es_id_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_external_es_id_descriptor\n");
+ dx = mpeg_external_es_id_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_external_es_id_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC external_es_id:0x%04x\n",
+ dx->external_es_id);
+ break;
+ }
+
+ case dtag_mpeg_muxcode:
+ {
+ struct mpeg_muxcode_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_muxcode_descriptor\n");
+ dx = mpeg_muxcode_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_muxcode_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC entries:\n");
+ hexdump(indent, "DSC ", mpeg_muxcode_descriptor_entries(dx), mpeg_muxcode_descriptor_entries_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_fmxbuffer_size:
+ {
+ struct mpeg_fmxbuffer_size_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_fmxbuffer_size_descriptor\n");
+ dx = mpeg_fmxbuffer_size_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_fmxbuffer_size_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC descriptors:\n");
+ hexdump(indent, "DSC ", mpeg_fmxbuffer_size_descriptor_descriptors(dx), mpeg_fmxbuffer_size_descriptor_descriptors_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_multiplex_buffer:
+ {
+ struct mpeg_multiplex_buffer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_multiplex_buffer_descriptor\n");
+ dx = mpeg_multiplex_buffer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_multiplex_buffer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mb_buffer_size:%i tb_leak_rate:%i\n",
+ dx->mb_buffer_size, dx->tb_leak_rate);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_content_labelling:
+ {
+ struct mpeg_content_labelling_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_content_labelling_descriptor\n");
+ dx = mpeg_content_labelling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_content_labelling_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_application_format:%04x\n",
+ dx->metadata_application_format);
+ struct mpeg_content_labelling_descriptor_application_format_identifier *id =
+ mpeg_content_labelling_descriptor_id(dx);
+ if (id != NULL) {
+ iprintf(indent, "DSC application_format_id:%04x\n",
+ id->id);
+ }
+ struct mpeg_content_labelling_descriptor_flags *flags =
+ mpeg_content_labelling_descriptor_flags(dx);
+ if (flags != NULL) {
+ iprintf(indent, "DSC content_reference_id_record_flag:%i content_time_base_indicator:%02x\n",
+ flags->content_reference_id_record_flag,
+ flags->content_time_base_indicator);
+
+ struct mpeg_content_labelling_descriptor_reference_id *reference_id =
+ mpeg_content_labelling_descriptor_reference_id(flags);
+ if (reference_id != NULL) {
+ hexdump(indent, "DSC reference_id " ,
+ mpeg_content_reference_id_data(reference_id),
+ reference_id->content_reference_id_record_length);
+ }
+
+ struct mpeg_content_labelling_descriptor_time_base *time_base =
+ mpeg_content_labelling_descriptor_time_base(flags);
+ if (time_base != NULL) {
+ iprintf(indent, "DSC time_base content_time_base_value:%lli metadata_time_base_value:%lli\n",
+ time_base->content_time_base_value,
+ time_base->metadata_time_base_value);
+ }
+
+ struct mpeg_content_labelling_descriptor_content_id *content_id =
+ mpeg_content_labelling_descriptor_content_id(flags);
+ if (content_id != NULL) {
+ iprintf(indent, "DSC content_id contentId:%i\n",
+ content_id->contentId);
+ }
+
+ struct mpeg_content_labelling_descriptor_time_base_association *time_base_assoc =
+ mpeg_content_labelling_descriptor_time_base_assoc(flags);
+ if (time_base_assoc != NULL) {
+ hexdump(indent, "DSC time_base_assoc" ,
+ mpeg_time_base_association_data(time_base_assoc),
+ time_base_assoc->time_base_association_data_length);
+ }
+
+ uint8_t *priv;
+ int priv_length;
+ priv = mpeg_content_labelling_descriptor_data(dx, flags, &priv_length);
+ hexdump(indent, "DSC private_data", priv, priv_length);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_metadata_pointer:
+ {
+ struct mpeg_metadata_pointer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_metadata_pointer_descriptor\n");
+ dx = mpeg_metadata_pointer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_metadata_pointer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_application_format:%04x\n",
+ dx->metadata_application_format);
+
+ struct mpeg_metadata_pointer_descriptor_application_format_identifier *id =
+ mpeg_metadata_pointer_descriptor_appid(dx);
+ if (id != NULL) {
+ iprintf(indent, "DSC application_format_id:%04x\n",
+ id->id);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_format_identifier *did =
+ mpeg_metadata_pointer_descriptor_formid(dx);
+ if (did != NULL) {
+ iprintf(indent, "DSC mpeg_metadata_pointer_descriptor_format_id:%04x\n",
+ did->id);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_flags *flags =
+ mpeg_metadata_pointer_descriptor_flags(dx);
+ if (flags != NULL) {
+ iprintf(indent, "DSC metadata_service_id:%i metadata_locator_record_flag:%i mpeg_carriage_flags:%x\n",
+ flags->metadata_service_id,
+ flags->metadata_locator_record_flag,
+ flags->mpeg_carriage_flags);
+
+ struct mpeg_metadata_pointer_descriptor_locator *locator =
+ mpeg_metadata_pointer_descriptor_locator(flags);
+ if (locator != NULL) {
+ hexdump(indent, "DSC locator" ,
+ mpeg_metadata_pointer_descriptor_locator_data(locator),
+ locator->metadata_locator_record_length);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_program_number *pnum=
+ mpeg_metadata_pointer_descriptor_program_number(flags);
+ if (pnum != NULL) {
+ iprintf(indent, "DSC program_number number:%04x\n",
+ pnum->number);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_carriage *carriage =
+ mpeg_metadata_pointer_descriptor_carriage(flags);
+ if (carriage != NULL) {
+ iprintf(indent, "DSC carriage transport_stream_location:%04x transport_stream_id:%04x\n",
+ carriage->transport_stream_location,
+ carriage->transport_stream_id);
+ }
+
+ uint8_t *priv;
+ int priv_length;
+ priv = mpeg_metadata_pointer_descriptor_private_data(dx, flags, &priv_length);
+ hexdump(indent, "DSC private_data" , priv, priv_length);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_metadata:
+ {
+ struct mpeg_metadata_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_metadata_descriptor\n");
+ dx = mpeg_metadata_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_metadata_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_application_format:%04x\n",
+ dx->metadata_application_format);
+
+ struct mpeg_metadata_descriptor_application_format_identifier *id =
+ mpeg_metadata_descriptor_appid(dx);
+ if (id != NULL) {
+ iprintf(indent, "DSC application_format_id:%04x\n",
+ id->id);
+ }
+
+ struct mpeg_metadata_descriptor_format_identifier *did =
+ mpeg_metadata_descriptor_formid(dx);
+ if (did != NULL) {
+ iprintf(indent, "DSC mpeg_metadata_descriptor_format_id:%04x\n",
+ did->id);
+ }
+
+ struct mpeg_metadata_descriptor_flags *flags =
+ mpeg_metadata_descriptor_flags(dx);
+ if (flags != NULL) {
+ iprintf(indent, "DSC metadata_service_id:%i decoder_config_flags:%i dsm_cc_flag:%x\n",
+ flags->metadata_service_id,
+ flags->decoder_config_flags,
+ flags->dsm_cc_flag);
+
+ struct mpeg_metadata_descriptor_service_identifier *serviceid=
+ mpeg_metadata_descriptor_sevice_identifier(flags);
+ if (serviceid != NULL) {
+ hexdump(indent, "DSC service_id" ,
+ mpeg_metadata_descriptor_service_identifier_data(serviceid),
+ serviceid->service_identification_length);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config *dconfig=
+ mpeg_metadata_descriptor_decoder_config(flags);
+ if (dconfig != NULL) {
+ hexdump(indent, "DSC decoder_config" ,
+ mpeg_metadata_descriptor_decoder_config_data(dconfig),
+ dconfig->decoder_config_length);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config_id_record *dconfigid=
+ mpeg_metadata_descriptor_decoder_config_id_record(flags);
+ if (dconfigid != NULL) {
+ hexdump(indent, "DSC decoder_config" ,
+ mpeg_metadata_descriptor_decoder_config_id_record_data(dconfigid),
+ dconfigid->decoder_config_id_record_length);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config_service_id *dserviceid=
+ mpeg_metadata_descriptor_decoder_config_service_id(flags);
+ if (dserviceid != NULL) {
+ iprintf(indent, "DSC decoder config service_id:%04x\n",
+ dserviceid->decoder_config_metadata_service_id);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config_reserved *reserved=
+ mpeg_metadata_descriptor_decoder_config_reserved(flags);
+ if (reserved != NULL) {
+ hexdump(indent, "DSC reserved" ,
+ mpeg_metadata_descriptor_decoder_config_reserved_data(reserved),
+ reserved->reserved_data_length);
+ }
+
+ uint8_t *priv;
+ int priv_length;
+ priv = mpeg_metadata_descriptor_private_data(dx, flags, &priv_length);
+ hexdump(indent, "DSC private_data" , priv, priv_length);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_metadata_std:
+ {
+ struct mpeg_metadata_std_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_metadata_std_descriptor\n");
+ dx = mpeg_metadata_std_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_metadata_std_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_input_leak_rate:%i metadata_buffer_size:%i metadata_output_leak_rate:%i\n",
+ dx->metadata_input_leak_rate,
+ dx->metadata_buffer_size,
+ dx->metadata_output_leak_rate);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ default:
+ switch(data_type) {
+ case DATA_TYPE_DVB:
+ parse_dvb_descriptor(d, indent, data_type);
+ return;
+
+ case DATA_TYPE_ATSC:
+ parse_atsc_descriptor(d, indent, data_type);
+ return;
+
+ default:
+ fprintf(stderr, "DSC XXXX Unknown descriptor_tag:0x%02x\n", d->tag);
+ hexdump(0, "DSC ", (uint8_t*) d, d->len+2);
+ return;
+ }
+ }
+}
+
+void parse_dvb_descriptor(struct descriptor *d, int indent, int data_type)
+{
+ (void) data_type;
+
+ switch(d->tag) {
+ case dtag_dvb_network_name:
+ {
+ struct dvb_network_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_network_name_descriptor\n");
+ dx = dvb_network_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_network_name_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC name:%.*s\n",
+ dvb_network_name_descriptor_name_length(dx),
+ dvb_network_name_descriptor_name(dx));
+ break;
+ }
+
+ case dtag_dvb_service_list:
+ {
+ struct dvb_service_list_descriptor *dx;
+ struct dvb_service_list_service *curs;
+
+ iprintf(indent, "DSC Decode dvb_service_list_descriptor\n");
+ dx = dvb_service_list_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_list_descriptor decode error\n");
+ return;
+ }
+ dvb_service_list_descriptor_services_for_each(dx, curs) {
+ iprintf(indent+1, "DSC service_id:0x%04x service_type:0x%02x\n",
+ curs->service_id, curs->service_type);
+ }
+ break;
+ }
+
+ case dtag_dvb_stuffing:
+ {
+ struct dvb_stuffing_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_stuffing_descriptor\n");
+ dx = dvb_stuffing_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_stuffing_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_stuffing_descriptor_data(dx),
+ dvb_stuffing_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_dvb_satellite_delivery_system:
+ {
+ struct dvb_satellite_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_satellite_delivery_descriptor\n");
+ dx = dvb_satellite_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_satellite_delivery_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC frequency:%i orbital_position:%i west_east:%i polarization:%i roll_off:%i modulation_system:%i modulation_type: %i symbol_rate:%i fec_inner:%i\n",
+ dx->frequency,
+ dx->orbital_position,
+ dx->west_east_flag,
+ dx->polarization,
+ dx->roll_off,
+ dx->modulation_system,
+ dx->modulation_type,
+ dx->symbol_rate,
+ dx->fec_inner);
+ break;
+ }
+
+ case dtag_dvb_cable_delivery_system:
+ {
+ struct dvb_cable_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_cable_delivery_descriptor\n");
+ dx = dvb_cable_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_cable_delivery_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC frequency:%i fec_outer:%i modulation:%i symbol_rate:%i fec_inner:%i\n",
+ dx->frequency, dx->fec_outer, dx->modulation,
+ dx->symbol_rate, dx->fec_inner);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_vbi_data:
+ {
+ struct dvb_vbi_data_descriptor *dx;
+ struct dvb_vbi_data_entry *cur;
+ struct dvb_vbi_data_x *curx;
+
+ iprintf(indent, "DSC Decode dvb_vbi_data_descriptor\n");
+ dx = dvb_vbi_data_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_vbi_data_descriptor decode error\n");
+ return;
+ }
+ dvb_vbi_data_descriptor_entries_for_each(dx, cur) {
+ curx = dvb_vbi_data_entry_data_x(cur);
+ iprintf(indent+1, "DSC data_service_id:0x%04x\n", cur->data_service_id);
+ if (cur == NULL) {
+ hexdump(indent+1, "DSC", dvb_vbi_data_entry_data(cur), cur->data_length);
+ } else {
+ iprintf(indent+1, "DSC field_parity:%i line_offset:%i\n",
+ curx->field_parity, curx->line_offset);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_vbi_teletext:
+ {
+ struct dvb_vbi_teletext_descriptor *dx;
+ struct dvb_vbi_teletext_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_vbi_teletext_descriptor\n");
+ dx = dvb_vbi_teletext_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_vbi_teletext_descriptor decode error\n");
+ return;
+ }
+ dvb_vbi_teletext_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1, "DSC language_code:%.3s type:%i magazine_number:%i page_number:%i\n",
+ cur->language_code,
+ cur->type, cur->magazine_number, cur->page_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_bouquet_name:
+ {
+ struct dvb_bouquet_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_bouquet_name_descriptor\n");
+ dx = dvb_bouquet_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_bouquet_name_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC name:%.*s\n",
+ dvb_bouquet_name_descriptor_name_length(dx),
+ dvb_bouquet_name_descriptor_name(dx));
+ break;
+ }
+
+ case dtag_dvb_service:
+ {
+ struct dvb_service_descriptor *dx;
+ struct dvb_service_descriptor_part2 *part2;
+
+ iprintf(indent, "DSC Decode dvb_service_descriptor\n");
+ dx = dvb_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_service_descriptor_part2(dx);
+ iprintf(indent, "DSC service_type:%02x provider_name:%.*s service_name:%.*s\n",
+ dx->service_type,
+ dx->service_provider_name_length,
+ dvb_service_descriptor_service_provider_name(dx),
+ part2->service_name_length,
+ dvb_service_descriptor_service_name(part2));
+ break;
+ }
+
+ case dtag_dvb_country_availability:
+ {
+ struct dvb_country_availability_descriptor *dx;
+ struct dvb_country_availability_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_country_availability_descriptor\n");
+ dx = dvb_country_availability_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_country_availability_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC country_availability_flag:%i\n", dx->country_availability_flag);
+ dvb_country_availability_descriptor_countries_for_each(dx, cur) {
+ iprintf(indent+1, "DSC country_code:%.3s\n", cur->country_code);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_linkage:
+ {
+ struct dvb_linkage_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_linkage_descriptor\n");
+ dx = dvb_linkage_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_linkage_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC transport_stream_id:0x%04x original_network_id:0x%04x service_id:0x%04x linkage_type:0x%02x\n",
+ dx->transport_stream_id, dx->original_network_id, dx->service_id, dx->linkage_type);
+ switch(dx->linkage_type) {
+ case 0x08:
+ {
+ struct dvb_linkage_data_08 *d08 = dvb_linkage_data_08(dx);
+ int network_id = dvb_linkage_data_08_network_id(dx, d08);
+ int initial_service_id = dvb_linkage_data_08_initial_service_id(dx, d08);
+ int length = 0;
+ uint8_t *data;
+
+ data = dvb_linkage_data_08_data(dx, d08, &length);
+ iprintf(indent, "DSC hand_over_type:%i origin_type:%i\n",
+ d08->hand_over_type, d08->origin_type);
+ if (network_id != -1) {
+ iprintf(indent, "DSC network_id:0x%04x\n", network_id);
+ }
+ if (initial_service_id != -1) {
+ iprintf(indent, "DSC initial_service_id:0x%04x\n", initial_service_id);
+ }
+ }
+
+ case 0x0b:
+ {
+ struct dvb_linkage_data_0b *data = dvb_linkage_data_0b(dx);
+ struct dvb_platform_id *platid;
+ struct dvb_platform_name *curplatname;
+
+ dvb_linkage_data_0b_platform_id_for_each(data, platid) {
+ iprintf(indent+1, "DSC platform_id:0x%06x\n", platid->platform_id);
+ dvb_platform_id_platform_name_for_each(platid, curplatname) {
+ iprintf(indent+2, "DSC language_code:%.3s platform_name:%.*s\n",
+ curplatname->language_code,
+ curplatname->platform_name_length, dvb_platform_name_text(curplatname));
+ }
+ }
+ break;
+ }
+
+ case 0x0c:
+ {
+ struct dvb_linkage_data_0c *data = dvb_linkage_data_0c(dx);
+
+ iprintf(indent, "DSC table_type:0x%02x\n", data->table_type);
+ if (dvb_linkage_data_0c_bouquet_id(data)) {
+ iprintf(indent, "DSC bouquet_id:0x%04x\n",
+ dvb_linkage_data_0c_bouquet_id(data));
+ }
+ break;
+ }
+
+ default:
+ hexdump(indent+1, "DSC", dvb_linkage_descriptor_data(dx), dvb_linkage_descriptor_data_length(dx));
+ break;
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_nvod_reference:
+ {
+ struct dvb_nvod_reference_descriptor *dx;
+ struct dvb_nvod_reference *cur;
+
+ iprintf(indent, "DSC Decode dvb_nvod_reference_descriptor\n");
+ dx = dvb_nvod_reference_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_nvod_reference_descriptor decode error\n");
+ return;
+ }
+ dvb_nvod_reference_descriptor_references_for_each(dx, cur) {
+ iprintf(indent+1, "DSC transport_stream_id:0x%04x original_network_id:0x%04x service_id:0x%04x\n",
+ cur->transport_stream_id, cur->original_network_id,
+ cur->service_id);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_time_shifted_service:
+ {
+ struct dvb_time_shifted_service_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_time_shifted_service_descriptor\n");
+ dx = dvb_time_shifted_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_time_shifted_service_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC reference_service_id:0x%04x\n", dx->reference_service_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_short_event:
+ {
+ struct dvb_short_event_descriptor *dx;
+ struct dvb_short_event_descriptor_part2 *part2;
+
+ iprintf(indent, "DSC Decode dvb_short_event_descriptor\n");
+ dx = dvb_short_event_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_short_event_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_short_event_descriptor_part2(dx);
+ iprintf(indent, "DSC language_code:%.3s event_name:%.*s text:%.*s\n",
+ dx->language_code,
+ dx->event_name_length, dvb_short_event_descriptor_event_name(dx),
+ part2->text_length, dvb_short_event_descriptor_text(part2));
+ break;
+ }
+
+ case dtag_dvb_extended_event:
+ {
+ struct dvb_extended_event_descriptor *dx;
+ struct dvb_extended_event_descriptor_part2 *part2;
+ struct dvb_extended_event_item *cur;
+
+ iprintf(indent, "DSC Decode dvb_extended_event_descriptor\n");
+ dx = dvb_extended_event_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_extended_event_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_extended_event_descriptor_part2(dx);
+ iprintf(indent, "DSC descriptor_number:%i last_descriptor_number:%i language_code:%.3s text:%.*s\n",
+ dx->descriptor_number, dx->last_descriptor_number,
+ dx->language_code,
+ part2->text_length, dvb_extended_event_descriptor_part2_text(part2));
+ dvb_extended_event_descriptor_items_for_each(dx, cur) {
+ struct dvb_extended_event_item_part2 *ipart2 =
+ dvb_extended_event_item_part2(cur);
+ iprintf(indent+1, "DSC description:%.*s item:%.*s\n",
+ cur->item_description_length, dvb_extended_event_item_description(cur),
+ ipart2->item_length, dvb_extended_event_item_part2_item(ipart2));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_time_shifted_event:
+ {
+ struct dvb_time_shifted_event_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_time_shifted_event_descriptor\n");
+ dx = dvb_time_shifted_event_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_time_shifted_event_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC reference_service_id:0x%04x reference_event_id:0x%04x\n",
+ dx->reference_service_id, dx->reference_event_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_component:
+ {
+ struct dvb_component_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_component_descriptor\n");
+ dx = dvb_component_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_component_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC stream_content:%i component_type:%i component_tag: %i language_code:%.3s, text:%.*s\n",
+ dx->stream_content,
+ dx->component_type,
+ dx->component_tag,
+ dx->language_code,
+ dvb_component_descriptor_text_length(dx),
+ dvb_component_descriptor_text(dx));
+ break;
+ }
+
+ case dtag_dvb_mosaic:
+ {
+ struct dvb_mosaic_descriptor *dx;
+ struct dvb_mosaic_info *curinfo;
+
+ iprintf(indent, "DSC Decode dvb_mosaic_descriptor\n");
+ dx = dvb_mosaic_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_mosaic_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mosaic_entry_point:%i number_of_horiz_elementary_cells:%i number_of_vert_elementary_cells:%i\n",
+ dx->mosaic_entry_point, dx->number_of_horiz_elementary_cells,
+ dx->number_of_vert_elementary_cells);
+ dvb_mosaic_descriptor_infos_for_each(dx, curinfo) {
+ struct dvb_mosaic_info_part2 *part2;
+ struct dvb_mosaic_linkage *linkage;
+ struct dvb_mosaic_elementary_cell_field *curfield;
+
+ part2 = dvb_mosaic_info_part2(curinfo);
+ linkage = dvb_mosaic_linkage(part2);
+ iprintf(indent+1, "DSC logical_cell_id:%i logical_cell_presentation_info:%i cell_linkage_info:0x%02x\n",
+ curinfo->logical_cell_id, curinfo->logical_cell_presentation_info,
+ part2->cell_linkage_info);
+ if (linkage) {
+ switch(part2->cell_linkage_info) {
+ case 0x01:
+ iprintf(indent+1, "DSC bouquet_id:0x%04x\n",
+ linkage->u.linkage_01.bouquet_id);
+ break;
+
+ case 0x02:
+ iprintf(indent+1, "DSC original_network_id:0x%04x transport_stream_id:0x%04x service_id:0x%04x\n",
+ linkage->u.linkage_02.original_network_id,
+ linkage->u.linkage_02.transport_stream_id,
+ linkage->u.linkage_02.service_id);
+ break;
+
+ case 0x03:
+ iprintf(indent+1, "DSC original_network_id:0x%04x transport_stream_id:0x%04x service_id:0x%04x\n",
+ linkage->u.linkage_03.original_network_id,
+ linkage->u.linkage_03.transport_stream_id,
+ linkage->u.linkage_03.service_id);
+ break;
+
+ case 0x04:
+ iprintf(indent+1, "DSC original_network_id:0x%04x transport_stream_id:0x%04x service_id:0x%04x event_id:0x%04x\n",
+ linkage->u.linkage_04.original_network_id,
+ linkage->u.linkage_04.transport_stream_id,
+ linkage->u.linkage_04.service_id,
+ linkage->u.linkage_04.event_id);
+ break;
+ }
+ }
+
+ dvb_mosaic_info_fields_for_each(curinfo, curfield) {
+ iprintf(indent+2, "DSC elementary_cell_id:0x%02x\n",
+ curfield->elementary_cell_id);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_stream_identifier:
+ {
+ struct dvb_stream_identifier_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_stream_identifier_descriptor\n");
+ dx = dvb_stream_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_stream_identifier_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC component_tag:%i\n",
+ dx->component_tag);
+ break;
+ }
+
+ case dtag_dvb_ca_identifier:
+ {
+ struct dvb_ca_identifier_descriptor *dx;
+ int i;
+ uint16_t *ids;
+
+ iprintf(indent, "DSC Decode dvb_ca_identifier_descriptor\n");
+ dx = dvb_ca_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_ca_identifier_descriptor decode error\n");
+ return;
+ }
+ ids = dvb_ca_identifier_descriptor_ca_system_ids(dx);
+ for(i=0; i< dvb_ca_identifier_descriptor_ca_system_ids_count(dx); i++) {
+ iprintf(indent+i, "DSC system_id:0x%04x\n", ids[i]);
+ }
+ break;
+ }
+
+ case dtag_dvb_content:
+ {
+ struct dvb_content_descriptor *dx;
+ struct dvb_content_nibble *cur;
+
+ iprintf(indent, "DSC Decode dvb_content_descriptor\n");
+ dx = dvb_content_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_content_descriptor decode error\n");
+ return;
+ }
+ dvb_content_descriptor_nibbles_for_each(dx, cur) {
+ iprintf(indent+1, "DSC content_nibble_level_1:%i content_nibble_level_2:%i user_nibble_1:%i user_nibble_2:%i\n",
+ cur->content_nibble_level_1, cur->content_nibble_level_2,
+ cur->user_nibble_1, cur->user_nibble_2);
+ }
+ break;
+ }
+
+ case dtag_dvb_parental_rating:
+ {
+ struct dvb_parental_rating_descriptor *dx;
+ struct dvb_parental_rating *cur;
+
+ iprintf(indent, "DSC Decode dvb_parental_rating_descriptor\n");
+ dx = dvb_parental_rating_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_parental_rating_descriptor decode error\n");
+ return;
+ }
+ dvb_parental_rating_descriptor_ratings_for_each(dx, cur) {
+ iprintf(indent+1, "DSC country_code:%.3s rating:%i\n",
+ cur->country_code, cur->rating);
+ }
+ break;
+ }
+
+ case dtag_dvb_teletext:
+ {
+ struct dvb_teletext_descriptor *dx;
+ struct dvb_teletext_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_teletext_descriptor\n");
+ dx = dvb_teletext_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_teletext_descriptor decode error\n");
+ return;
+ }
+ dvb_teletext_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1, "DSC language_code:%.3s type:%i magazine_number:%i page_number:%i\n",
+ cur->language_code,
+ cur->type, cur->magazine_number, cur->page_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_telephone:
+ {
+ struct dvb_telephone_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_telephone_descriptor\n");
+ dx = dvb_telephone_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_telephone_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC foreign_availability:%i connection_type:%i country_prefix:%.*s "
+ "international_area_code:%.*s operator_code:%.*s national_area_code:%.*s core_number:%.*s\n",
+ dx->foreign_availability, dx->connection_type,
+ dx->country_prefix_length, dvb_telephone_descriptor_country_prefix(dx),
+ dx->international_area_code_length, dvb_telephone_descriptor_international_area_code(dx),
+ dx->operator_code_length, dvb_telephone_descriptor_operator_code(dx),
+ dx->national_area_code_length, dvb_telephone_descriptor_national_area_code(dx),
+ dx->core_number_length, dvb_telephone_descriptor_core_number(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_local_time_offset:
+ {
+ struct dvb_local_time_offset_descriptor *dx;
+ struct dvb_local_time_offset *cur;
+
+ iprintf(indent, "DSC Decode dvb_local_time_offset_descriptor\n");
+ dx = dvb_local_time_offset_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_local_time_offset_descriptor decode error\n");
+ return;
+ }
+ dvb_local_time_offset_descriptor_offsets_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC country_code:%.3s country_region_id:%i "
+ "local_time_offset_polarity:%i local_time_offset:%i "
+ "time_of_change:%i next_time_offset:%i\n",
+ cur->country_code, cur->country_region_id,
+ cur->local_time_offset_polarity,
+ dvbhhmm_to_seconds(cur->local_time_offset),
+ dvbdate_to_unixtime(cur->time_of_change),
+ dvbhhmm_to_seconds(cur->next_time_offset));
+ }
+ break;
+ }
+
+ case dtag_dvb_subtitling:
+ {
+ struct dvb_subtitling_descriptor *dx;
+ struct dvb_subtitling_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_subtitling_descriptor\n");
+ dx = dvb_subtitling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_subtitling_descriptor decode error\n");
+ return;
+ }
+ dvb_subtitling_descriptor_subtitles_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s subtitling_type:0x%02x composition_page_id:0x%04x ancillary_page_id:0x%04x\n",
+ cur->language_code, cur->subtitling_type,
+ cur->composition_page_id, cur->ancillary_page_id);
+ }
+ break;
+ }
+
+ case dtag_dvb_terrestial_delivery_system:
+ {
+ struct dvb_terrestrial_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_terrestrial_delivery_descriptor\n");
+ dx = dvb_terrestrial_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_terrestrial_delivery_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC centre_frequency:%i bandwidth:%i priority:%i "
+ "time_slicing_indicator:%i mpe_fec_indicator:%i constellation:%i "
+ "hierarchy_information:%i code_rate_hp_stream:%i "
+ "code_rate_lp_stream:%i guard_interval:%i transmission_mode:%i "
+ "other_frequency_flag:%i\n",
+ dx->centre_frequency, dx->bandwidth, dx->priority,
+ dx->time_slicing_indicator, dx->mpe_fec_indicator,
+ dx->constellation,
+ dx->hierarchy_information, dx->code_rate_hp_stream,
+ dx->code_rate_lp_stream, dx->guard_interval,
+ dx->transmission_mode, dx->other_frequency_flag);
+ break;
+ }
+
+ case dtag_dvb_multilingual_network_name:
+ {
+ struct dvb_multilingual_network_name_descriptor *dx;
+ struct dvb_multilingual_network_name *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_network_name_descriptor\n");
+ dx = dvb_multilingual_network_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_network_name_descriptor decode error\n");
+ return;
+ }
+ dvb_multilingual_network_name_descriptor_names_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s network_name:%.*s\n",
+ cur->language_code,
+ cur->network_name_length,
+ dvb_multilingual_network_name_name(cur));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_multilingual_bouquet_name:
+ {
+ struct dvb_multilingual_bouquet_name_descriptor *dx;
+ struct dvb_multilingual_bouquet_name *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_bouquet_name_descriptor\n");
+ dx = dvb_multilingual_bouquet_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_bouquet_name_descriptor decode error\n");
+ return;
+ }
+ dvb_multilingual_bouquet_name_descriptor_names_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s bouquet_name:%.*s\n",
+ cur->language_code,
+ cur->bouquet_name_length,
+ dvb_multilingual_bouquet_name_name(cur));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_multilingual_service_name:
+ {
+ struct dvb_multilingual_service_name_descriptor *dx;
+ struct dvb_multilingual_service_name *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_service_name_descriptor\n");
+ dx = dvb_multilingual_service_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_service_name_descriptor decode error\n");
+ return;
+ }
+ dvb_multilingual_service_name_descriptor_names_for_each(dx, cur) {
+ struct dvb_multilingual_service_name_part2 *part2;
+ part2 = dvb_multilingual_service_name_part2(cur);
+
+ iprintf(indent+1,
+ "DSC language_code:%.3s provider_name:%.*s service_name:%.*s\n",
+ cur->language_code,
+ cur->service_provider_name_length,
+ dvb_multilingual_service_name_service_provider_name(cur),
+ part2->service_name_length,
+ dvb_multilingual_service_name_service_name(part2));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_multilingual_component:
+ {
+ struct dvb_multilingual_component_descriptor *dx;
+ struct dvb_multilingual_component *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_component_descriptor\n");
+ dx = dvb_multilingual_component_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_component_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC component_tag:%02x\n", dx->component_tag);
+ dvb_multilingual_component_descriptor_components_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s description:%.*s\n",
+ cur->language_code,
+ cur->text_description_length,
+ dvb_multilingual_component_text_char(cur));
+ }
+ break;
+ }
+
+ case dtag_dvb_private_data_specifier:
+ {
+ struct dvb_private_data_specifier_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_private_data_specifier_descriptor\n");
+ dx = dvb_private_data_specifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_private_data_specifier_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC private_data_specifier:0x%08x\n",
+ dx->private_data_specifier);
+ break;
+ }
+
+ case dtag_dvb_service_move:
+ {
+ struct dvb_service_move_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_service_move_descriptor\n");
+ dx = dvb_service_move_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_move_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC new_original_network_id:0x%04x new_transport_stream_id:0x%04x new_service_id:0x%04x\n",
+ dx->new_original_network_id, dx->new_transport_stream_id, dx->new_service_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_short_smoothing_buffer:
+ {
+ struct dvb_short_smoothing_buffer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_short_smoothing_buffer_descriptor\n");
+ dx = dvb_short_smoothing_buffer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_short_smoothing_buffer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC sb_size:%i sb_leak_rate:%i\n",
+ dx->sb_size, dx->sb_leak_rate);
+ hexdump(indent, "DSC",
+ dvb_short_smoothing_buffer_descriptor_reserved(dx),
+ dvb_short_smoothing_buffer_descriptor_reserved_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_frequency_list:
+ {
+ struct dvb_frequency_list_descriptor *dx;
+ uint32_t *freqs;
+ int count;
+ int i;
+
+ iprintf(indent, "DSC Decode dvb_frequency_list_descriptor\n");
+ dx = dvb_frequency_list_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_frequency_list_descriptor decode error\n");
+ return;
+ }
+ iprintf(0, "DSC coding_type=%i\n", dx->coding_type);
+
+ freqs = dvb_frequency_list_descriptor_centre_frequencies(dx);
+ count = dvb_frequency_list_descriptor_centre_frequencies_count(dx);
+ for(i=0; i< count; i++) {
+ iprintf(indent+1, "DSC %i\n", freqs[i]);
+ }
+ break;
+ }
+
+ case dtag_dvb_partial_transport_stream:
+ {
+ struct dvb_partial_transport_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_partial_transport_stream_descriptor\n");
+ dx = dvb_partial_transport_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_partial_transport_stream_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC peak_rate:%i minimum_overall_smoothing_rate:%i maximum_overall_smoothing_rate:%i\n",
+ dx->peak_rate, dx->minimum_overall_smoothing_rate, dx->maximum_overall_smoothing_rate);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_data_broadcast:
+ {
+ struct dvb_data_broadcast_descriptor *dx;
+ struct dvb_data_broadcast_descriptor_part2 *part2;
+
+ iprintf(indent, "DSC Decode dvb_data_broadcast_descriptor\n");
+ dx = dvb_data_broadcast_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_data_broadcast_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_data_broadcast_descriptor_part2(dx);
+
+ iprintf(indent, "DSC data_broadcast_id:0x%04x component_tag:0x%02x selector:%.*s language_code:%.3s text:%.*s\n",
+ dx->data_broadcast_id, dx->component_tag,
+ dx->selector_length, dvb_data_broadcast_descriptor_selector(dx),
+ part2->language_code,
+ part2->text_length, dvb_data_broadcast_descriptor_part2_text(part2));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_scrambling:
+ {
+ struct dvb_scrambling_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_scrambling_descriptor\n");
+ dx = dvb_scrambling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_scrambling_descriptor decode error\n");
+ return;
+ }
+
+ iprintf(indent, "DSC scrambling_mode:0x%02x\n",
+ dx->scrambling_mode);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_data_broadcast_id:
+ {
+ struct dvb_data_broadcast_id_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_data_broadcast_id_descriptor\n");
+ dx = dvb_data_broadcast_id_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_data_broadcast_id_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC data_broadcast_id:0x%04x\n",
+ dx->data_broadcast_id);
+ hexdump(indent+1, "DSC",
+ dvb_data_broadcast_id_descriptor_id_selector_byte(dx),
+ dvb_data_broadcast_id_descriptor_id_selector_byte_length(dx));
+ break;
+ }
+
+ case dtag_dvb_transport_stream:
+ {
+ struct dvb_transport_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_transport_stream_descriptor\n");
+ dx = dvb_transport_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_transport_stream_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_transport_stream_descriptor_data(dx),
+ dvb_transport_stream_descriptor_data_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_dsng:
+ {
+ struct dvb_dsng_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_dsng_descriptor\n");
+ dx = dvb_dsng_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_dsng_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_dsng_descriptor_data(dx),
+ dvb_dsng_descriptor_data_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_pdc:
+ {
+ struct dvb_pdc_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_pdc_descriptor\n");
+ dx = dvb_pdc_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_pdc_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC programme_id_label:0x%06x\n",
+ dx->programme_id_label);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_ac3:
+ {
+ struct dvb_ac3_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_ac3_descriptor\n");
+ dx = dvb_ac3_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_ac3_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC ac3_type_flag:%i bsid_flag:%i mainid_flag:%i asvc_flag:%i\n",
+ dx->ac3_type_flag, dx->bsid_flag, dx->mainid_flag, dx->asvc_flag);
+ hexdump(indent+1, "DSC",
+ dvb_ac3_descriptor_additional_info(dx),
+ dvb_ac3_descriptor_additional_info_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_ancillary_data:
+ {
+ struct dvb_ancillary_data_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_ancillary_data_descriptor\n");
+ dx = dvb_ancillary_data_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_ancillary_data_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC scale_factor_error_check:%i dab_ancillary_data:%i announcement_switching_data:%i extended_ancillary_data:%i dvd_video_ancillary_data:%i\n",
+ dx->scale_factor_error_check,
+ dx->dab_ancillary_data,
+ dx->announcement_switching_data,
+ dx->extended_ancillary_data,
+ dx->dvd_video_ancillary_data);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_cell_list:
+ {
+ struct dvb_cell_list_descriptor *dx;
+ struct dvb_cell_list_entry *cur;
+ struct dvb_subcell_list_entry *cur_subcell;
+
+ iprintf(indent, "DSC Decode dvb_cell_list_descriptor\n");
+ dx = dvb_cell_list_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_cell_list_descriptor decode error\n");
+ return;
+ }
+ dvb_cell_list_descriptor_cells_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC cell_id:%04x cell_latitude:%i cell_longitude:%i cell_extend_of_latitude:%i cell_extend_of_longitude:%i\n",
+ cur->cell_id,
+ cur->cell_latitude,
+ cur->cell_longitude,
+ cur->cell_extend_of_latitude,
+ cur->cell_extend_of_longitude);
+
+ dvb_cell_list_entry_subcells_for_each(cur, cur_subcell) {
+ iprintf(indent+2,
+ "DSC cell_id_extension:%04x subcell_latitude:%i subcell_longitude:%i subcell_extend_of_latitude:%i subcell_extend_of_longitude:%i\n",
+ cur_subcell->cell_id_extension,
+ cur_subcell->subcell_latitude,
+ cur_subcell->subcell_longitude,
+ cur_subcell->subcell_extend_of_latitude,
+ cur_subcell->subcell_extend_of_longitude);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_cell_frequency_link:
+ {
+ struct dvb_cell_frequency_link_descriptor *dx;
+ struct dvb_cell_frequency_link_cell *cur;
+ struct dvb_cell_frequency_link_cell_subcell *cur_subcell;
+
+ iprintf(indent, "DSC Decode dvb_cell_frequency_link_descriptor\n");
+ dx = dvb_cell_frequency_link_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_cell_frequency_link_descriptor decode error\n");
+ return;
+ }
+ dvb_cell_frequency_link_descriptor_cells_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC cell_id:%04x frequency:%i\n",
+ cur->cell_id,
+ cur->frequency);
+
+ dvb_cell_frequency_link_cell_subcells_for_each(cur, cur_subcell) {
+ iprintf(indent+2,
+ "DSC cell_id_extension:%04x transposer_frequency:%i\n",
+ cur_subcell->cell_id_extension,
+ cur_subcell->transposer_frequency);
+ }
+ }
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_announcement_support:
+ {
+ struct dvb_announcement_support_descriptor *dx;
+ struct dvb_announcement_support_entry *cur;
+ struct dvb_announcement_support_reference *ref;
+
+ iprintf(indent, "DSC Decode dvb_announcement_support_descriptor\n");
+ dx = dvb_announcement_support_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_announcement_support_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC announcement_support_indicator:%04x\n",
+ dx->announcement_support_indicator);
+
+ dvb_announcement_support_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC announcement_type:%i reference_type:%i\n",
+ cur->announcement_type,
+ cur->reference_type);
+
+ ref = dvb_announcement_support_entry_reference(cur);
+ if (ref) {
+ iprintf(indent+1,
+ "DSC original_network_id:%04x transport_stream_id:%04x service_id:%04x component_tag:%02x\n",
+ ref->original_network_id,
+ ref->transport_stream_id,
+ ref->service_id,
+ ref->component_tag);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_application_signalling:
+ {
+ struct dvb_application_signalling_descriptor *dx;
+ struct dvb_application_signalling_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_application_signalling_descriptor\n");
+ dx = dvb_application_signalling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_application_signalling_descriptor decode error\n");
+ return;
+ }
+
+ dvb_application_signalling_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC application_type:%i AIT_version_number:%i\n",
+ cur->application_type,
+ cur->AIT_version_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_adaptation_field_data:
+ {
+ struct dvb_adaptation_field_data_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_adaptation_field_data_descriptor\n");
+ dx = dvb_adaptation_field_data_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_adaptation_field_data_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC announcement_switching_data:%i\n",
+ dx->announcement_switching_data);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_service_identifier:
+ {
+ struct dvb_service_identifier_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_service_identifier_descriptor\n");
+ dx = dvb_service_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_identifier_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_service_identifier_descriptor_identifier(dx),
+ dvb_service_identifier_descriptor_identifier_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_service_availability:
+ {
+ struct dvb_service_availability_descriptor *dx;
+ uint16_t *cellids;
+ int count;
+ int i;
+
+ iprintf(indent, "DSC Decode dvb_service_availability_descriptor\n");
+ dx = dvb_service_availability_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_availability_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC availability_flag:%i\n",
+ dx->availability_flag);
+
+ cellids = dvb_service_availability_descriptor_cell_ids(dx);
+ count = dvb_service_availability_descriptor_cell_ids_count(dx);
+ for(i=0; i< count; i++) {
+ iprintf(indent+1, "DSC", "%04x\n", cellids[i]);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_default_authority:
+ {
+ struct dvb_default_authority_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_default_authority_descriptor\n");
+ dx = dvb_default_authority_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_default_authority_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_default_authority_descriptor_name(dx),
+ dvb_default_authority_descriptor_name_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_related_content:
+ {
+ struct dvb_related_content_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_related_content_descriptor\n");
+ dx = dvb_related_content_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_related_content_descriptor decode error\n");
+ return;
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_tva_id:
+ {
+ struct dvb_tva_id_descriptor *dx;
+ struct dvb_tva_id_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_tva_id_descriptor\n");
+ dx = dvb_tva_id_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_tva_id_descriptor decode error\n");
+ return;
+ }
+
+ dvb_tva_id_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC tva_id:%04x running_status:%i\n",
+ cur->tva_id,
+ cur->running_status);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_content_identifier:
+ {
+ struct dvb_content_identifier_descriptor *dx;
+ struct dvb_content_identifier_entry *cur;
+ struct dvb_content_identifier_entry_data_0 *data0;
+ struct dvb_content_identifier_entry_data_1 *data1;
+
+ iprintf(indent, "DSC Decode dvb_tva_id_descriptor\n");
+ dx = dvb_content_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_content_identifier_descriptor decode error\n");
+ return;
+ }
+
+ dvb_content_identifier_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC crid_type:%i crid_location:%i\n",
+ cur->crid_type,
+ cur->crid_location);
+
+ data0 = dvb_content_identifier_entry_data_0(cur);
+ if (data0) {
+ hexdump(indent, "DSC data0",
+ dvb_content_identifier_entry_data_0_data(data0),
+ data0->crid_length);
+ }
+
+ data1 = dvb_content_identifier_entry_data_1(cur);
+ if (data1) {
+ iprintf(indent+1,
+ "DSC crid_ref:%04x\n",
+ data1->crid_ref);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_s2_satellite_delivery_descriptor:
+ {
+ struct dvb_s2_satellite_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_s2_satellite_delivery_descriptor\n");
+ dx = dvb_s2_satellite_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_s2_satellite_delivery_descriptor decode error\n");
+ return;
+ }
+
+ iprintf(indent,
+ "DSC scrambling_sequence_selector:%i multiple_input_stream:%i backwards_compatability:%i\n",
+ dx->scrambling_sequence_selector,
+ dx->multiple_input_stream,
+ dx->backwards_compatability);
+ if (dx->scrambling_sequence_selector) {
+ iprintf(indent,
+ "DSC scrambling_sequence_index:%i\n",
+ dvb_s2_satellite_delivery_descriptor_scrambling_sequence_index(dx));
+ }
+ if (dx->multiple_input_stream) {
+ iprintf(indent,
+ "DSC input_stream_id:%i\n",
+ dvb_s2_satellite_delivery_descriptor_input_stream_id(dx));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ default:
+ fprintf(stderr, "DSC XXXX Unknown descriptor_tag:0x%02x\n", d->tag);
+ hexdump(0, "DSC ", (uint8_t*) d, d->len+2);
+ return;
+ }
+}
+
+void parse_atsc_descriptor(struct descriptor *d, int indent, int data_type)
+{
+ (void) data_type;
+
+ switch(d->tag) {
+ case dtag_atsc_stuffing:
+ {
+ struct atsc_stuffing_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_stuffing_descriptor\n");
+ dx = atsc_stuffing_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_stuffing_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ atsc_stuffing_descriptor_data(dx),
+ atsc_stuffing_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_atsc_ac3_audio:
+ {
+ struct atsc_ac3_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_ac3_descriptor\n");
+ dx = atsc_ac3_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_ac3_descriptor decode error\n");
+ return;
+ }
+
+ iprintf(indent,
+ "DSC sample_rate_code:%i bsid:%i bit_rate_code:%i surround_mode:%i bsmod:%i num_channels:%i full_svc:%i\n",
+ dx->sample_rate_code,
+ dx->bsid,
+ dx->bit_rate_code,
+ dx->surround_mode,
+ dx->bsmod,
+ dx->num_channels,
+ dx->full_svc);
+
+ hexdump(indent+1, "DSC additional_info",
+ atsc_ac3_descriptor_additional_info(dx),
+ atsc_ac3_descriptor_additional_info_length(dx));
+ break;
+ }
+
+ case dtag_atsc_caption_service:
+ {
+ struct atsc_caption_service_descriptor *dx;
+ struct atsc_caption_service_entry *cur;
+ int idx;
+
+ iprintf(indent, "DSC Decode atsc_caption_service_descriptor\n");
+ dx = atsc_caption_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_caption_service_descriptor decode error\n");
+ return;
+ }
+
+ atsc_caption_service_descriptor_entries_for_each(dx, cur, idx) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s digital_cc:%i value:%i easy_reader:%i wide_aspect_ratio:%i\n",
+ cur->language_code,
+ cur->digital_cc,
+ cur->value,
+ cur->easy_reader,
+ cur->wide_aspect_ratio);
+ }
+ break;
+ }
+
+ case dtag_atsc_content_advisory:
+ {
+ struct atsc_content_advisory_descriptor *dx;
+ struct atsc_content_advisory_entry *cure;
+ struct atsc_content_advisory_entry_dimension *curd;
+ struct atsc_content_advisory_entry_part2 *part2;
+ int eidx;
+ int didx;
+
+ iprintf(indent, "DSC Decode atsc_content_advisory_descriptor\n");
+ dx = atsc_content_advisory_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_content_advisory_descriptor decode error\n");
+ return;
+ }
+
+ atsc_content_advisory_descriptor_entries_for_each(dx, cure, eidx) {
+ iprintf(indent+1,
+ "DSC rating_region:%i\n",
+ cure->rating_region);
+
+ atsc_content_advisory_entry_dimensions_for_each(cure, curd, didx) {
+ iprintf(indent+2,
+ "DSC rating_dimension_j:%i rating_value:%i\n",
+ curd->rating_dimension_j,
+ curd->rating_value);
+ }
+
+ part2 = atsc_content_advisory_entry_part2(cure);
+
+ atsctextdump("DSC description:",
+ indent,
+ atsc_content_advisory_entry_part2_description(part2),
+ part2->rating_description_length);
+ }
+
+ break;
+ }
+
+ case dtag_atsc_extended_channel_name:
+ {
+ struct atsc_extended_channel_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_extended_channel_name_descriptor\n");
+ dx = atsc_extended_channel_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_extended_channel_name_descriptor decode error\n");
+ return;
+ }
+
+ atsctextdump("SCT text:", 1,
+ atsc_extended_channel_name_descriptor_text(dx),
+ atsc_extended_channel_name_descriptor_text_length(dx));
+ break;
+ }
+
+ case dtag_atsc_service_location:
+ {
+ struct atsc_service_location_descriptor *dx;
+ struct atsc_caption_service_location_element *cur;
+ int idx;
+
+ iprintf(indent, "DSC Decode atsc_service_location_descriptor\n");
+ dx = atsc_service_location_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_service_location_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent+1, "DSC PCR_PID:%04x\n", dx->PCR_PID);
+
+ atsc_service_location_descriptor_elements_for_each(dx, cur, idx) {
+ iprintf(indent+1, "DSC stream_type:%02x elementary_PID:%04x language_code:%.3s\n",
+ cur->stream_type,
+ cur->elementary_PID,
+ cur->language_code);
+ }
+ break;
+ }
+
+ case dtag_atsc_time_shifted_service:
+ {
+ struct atsc_time_shifted_service_descriptor *dx;
+ struct atsc_time_shifted_service *cur;
+ int idx;
+
+ iprintf(indent, "DSC Decode atsc_time_shifted_service_descriptor\n");
+ dx = atsc_time_shifted_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_time_shifted_service_descriptor decode error\n");
+ return;
+ }
+
+ atsc_time_shifted_service_descriptor_services_for_each(dx, cur, idx) {
+ iprintf(indent+1, "DSC time_shift:%i major_channel_number:%04x minor_channel_number:%04x\n",
+ cur->time_shift,
+ cur->major_channel_number,
+ cur->minor_channel_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_component_name:
+ {
+ struct atsc_component_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_component_name_descriptor\n");
+ dx = atsc_component_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_component_name_descriptor decode error\n");
+ return;
+ }
+
+ atsctextdump("SCT name:", 1,
+ atsc_component_name_descriptor_text(dx),
+ atsc_component_name_descriptor_text_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_dcc_departing_request:
+ {
+ struct atsc_dcc_departing_request_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_dcc_departing_request_descriptor\n");
+ dx = atsc_dcc_departing_request_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_dcc_departing_request_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent+1, "DSC dcc_departing_request_type:%02x\n",
+ dx->dcc_departing_request_type);
+
+ atsctextdump("SCT text:", 1,
+ atsc_dcc_departing_request_descriptor_text(dx),
+ atsc_dcc_departing_request_descriptor_text_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_dcc_arriving_request:
+ {
+ struct atsc_dcc_arriving_request_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_dcc_arriving_request_descriptor\n");
+ dx = atsc_dcc_arriving_request_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_dcc_arriving_request_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent+1, "DSC dcc_arriving_request_type:%02x\n",
+ dx->dcc_arriving_request_type);
+
+ atsctextdump("SCT text:", 1,
+ atsc_dcc_arriving_request_descriptor_text(dx),
+ atsc_dcc_arriving_request_descriptor_text_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_redistribution_control:
+ {
+ struct atsc_rc_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_rc_descriptor\n");
+ dx = atsc_rc_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_rc_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ atsc_rc_descriptor_info(dx),
+ atsc_rc_descriptor_info_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_genre:
+ {
+ struct atsc_genre_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_genre_descriptor\n");
+ dx = atsc_genre_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_genre_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ atsc_genre_descriptor_attributes(dx),
+ dx->attribute_count);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_private_information:
+ // FIXME: whats the format?
+
+ case dtag_atsc_content_identifier:
+ // FIXME: whats the format?
+
+ default:
+ fprintf(stderr, "DSC XXXX Unknown descriptor_tag:0x%02x\n", d->tag);
+ hexdump(0, "DSC ", (uint8_t*) d, d->len+2);
+ return;
+ }
+}
+
+void iprintf(int indent, char *fmt, ...)
+{
+ va_list ap;
+
+ while(indent--) {
+ printf("\t");
+ }
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
+void hexdump(int indent, char *prefix, uint8_t *buf, int buflen)
+{
+ int i;
+ int j;
+ int max;
+ char line[512];
+
+ for(i=0; i< buflen; i+=16) {
+ max = 16;
+ if ((i + max) > buflen)
+ max = buflen - i;
+
+ memset(line, 0, sizeof(line));
+ memset(line + 4 + 48 + 1, ' ', 16);
+ sprintf(line, "%02x: ", i);
+ for(j=0; j<max; j++) {
+ sprintf(line + 4 + (j*3), "%02x", buf[i+j]);
+ if ((buf[i+j] > 31) && (buf[i+j] < 127))
+ line[4 + 48 + 1 + j] = buf[i+j];
+ else
+ line[4 + 48 + 1 + j] = '.';
+ }
+
+ for(j=0; j< 4 + 48; j++) {
+ if (!line[j])
+ line[j] = ' ';
+ }
+ line[4+48] = '|';
+
+ for(j=0; j < indent; j++) {
+ printf("\t");
+ }
+ printf("%s%s|\n", prefix, line);
+ }
+}
+
+void atsctextdump(char *header, int indent, struct atsc_text *atext, int len)
+{
+ struct atsc_text_string *cur_string;
+ struct atsc_text_string_segment *cur_segment;
+ int str_idx;
+ int seg_idx;
+
+ if (len == 0)
+ return;
+
+ atsc_text_strings_for_each(atext, cur_string, str_idx) {
+ iprintf(indent+1, "%s String %i language:%.3s\n", header, str_idx, cur_string->language_code);
+
+ atsc_text_string_segments_for_each(cur_string, cur_segment, seg_idx) {
+ iprintf(indent+2, "Segment %i compression_type:%i mode:%i\n",
+ seg_idx,
+ cur_segment->compression_type,
+ cur_segment->mode);
+
+ hexdump(indent+2, "rawbytes ",
+ atsc_text_string_segment_bytes(cur_segment),
+ cur_segment->number_bytes);
+
+ if (cur_segment->compression_type < 0x3e) {
+ uint8_t *decoded = NULL;
+ size_t decodedlen = 0;
+ size_t decodedpos = 0;
+
+ if (atsc_text_segment_decode(cur_segment,
+ &decoded,
+ &decodedlen,
+ &decodedpos) < 0) {
+ iprintf(indent+2, "Decode error\n");
+ } else {
+ hexdump(indent+2, "decoded ", decoded, decodedpos);
+ }
+ if (decoded)
+ free(decoded);
+ }
+ }
+ }
+}
diff --git a/util/lib/lnb.c b/test/lnb.c
index d082181..9052d1c 100644
--- a/util/lib/lnb.c
+++ b/test/lnb.c
@@ -12,7 +12,7 @@ static char *univ_desc[] = {
static char *dbs_desc[] = {
"Expressvu, North America",
"12200 to 12700 MHz",
- "Single LO, 11250 MHz",
+ "Single LO, 11250 MHz",
(char *)NULL };
static char *standard_desc[] = {
@@ -47,7 +47,7 @@ static struct lnb_types_st lnbs[] = {
struct lnb_types_st *
lnb_enum(int curno)
{
- if (curno >= sizeof(lnbs) / sizeof(lnbs[0]))
+ if (curno >= (int) (sizeof(lnbs) / sizeof(lnbs[0])))
return (struct lnb_types_st *)NULL;
return &lnbs[curno];
}
@@ -68,7 +68,7 @@ char *cp, *np;
while(*cp && isspace(*cp))
cp++;
if (isalpha(*cp)) {
- for(i = 0; i < (sizeof(lnbs) / sizeof(lnbs[0])); i++) {
+ for (i = 0; i < (int)(sizeof(lnbs) / sizeof(lnbs[0])); i++) {
if (!strcasecmp(lnbs[i].name, cp)) {
*lnbp = lnbs[i];
return 1;
diff --git a/util/lib/lnb.h b/test/lnb.h
index f78b7a6..6370fd4 100644
--- a/util/lib/lnb.h
+++ b/test/lnb.h
@@ -1,4 +1,3 @@
-
struct lnb_types_st {
char *name;
char **desc;
@@ -21,4 +20,3 @@ lnb_enum(int curno);
int
lnb_decode(char *str, struct lnb_types_st *lnbp);
-
diff --git a/test/sendburst.c b/test/sendburst.c
index a96b68c..b19df37 100644
--- a/test/sendburst.c
+++ b/test/sendburst.c
@@ -1,8 +1,9 @@
-/*
- * Test sending the burst mini command A/B on a SAT frontend.
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX sendburst {a|b}
- */
+#define USAGE \
+"\n" \
+"\nTest sending the burst mini command A/B on a SAT frontend." \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX sendburst {a|b}" \
+"\n"
#include <stdlib.h>
#include <stdio.h>
@@ -22,7 +23,7 @@ int main (int argc, char **argv)
int fd, r;
if (argc != 2 || (strcmp(argv[1], "a") && strcmp(argv[1], "b"))) {
- fprintf (stderr, "usage: %s <a|b>\n", argv[0]);
+ fprintf (stderr, "usage: %s <a|b>\n" USAGE, argv[0]);
return 1;
}
@@ -52,4 +53,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/test/set22k.c b/test/set22k.c
index 51ffa1c..a9f0d8c 100644
--- a/test/set22k.c
+++ b/test/set22k.c
@@ -1,10 +1,11 @@
-/*
- * Test switching the 22kHz tone signal on and off on a SAT frontend.
- * (Note: DiSEqC equipment ignores this after it has once seen a diseqc
- * sequence; reload the driver or unplug/replug the SAT cable to reset.)
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX set22k {on|off}
- */
+#define USAGE \
+"\n" \
+"\nTest switching the 22kHz tone signal on and off on a SAT frontend." \
+"\n(Note: DiSEqC equipment ignores this after it has once seen a diseqc" \
+"\n sequence; reload the driver or unplug/replug the SAT cable to reset.)" \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX set22k {on|off}" \
+"\n"
#include <stdlib.h>
#include <stdio.h>
@@ -24,7 +25,7 @@ int main (int argc, char **argv)
int fd, r;
if (argc != 2 || (strcmp(argv[1], "on") && strcmp(argv[1], "off"))) {
- fprintf (stderr, "usage: %s <on|off>\n", argv[0]);
+ fprintf (stderr, "usage: %s <on|off>\n" USAGE, argv[0]);
return 1;
}
if (getenv("FRONTEND"))
@@ -47,4 +48,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/test/setpid.c b/test/setpid.c
index fa0333c..a2d42cf 100644
--- a/test/setpid.c
+++ b/test/setpid.c
@@ -1,9 +1,10 @@
-/*
- * Set video and audio PIDs in the demux; useful only if you have
- * a hardware MPEG decoder and you're tuned to a transport stream.
- *
- * usage: DEMUX=/dev/dvb/adapterX/demuxX setpid video_pid audio_pid
- */
+#define USAGE \
+"\n" \
+"\nSet video and audio PIDs in the demux; useful only if you have" \
+"\na hardware MPEG decoder and you're tuned to a transport stream." \
+"\n" \
+"\nusage: DEMUX=/dev/dvb/adapterX/demuxX setpid video_pid audio_pid" \
+"\n"
#include <unistd.h>
#include <stdlib.h>
@@ -69,7 +70,7 @@ int main (int argc, char **argv)
int video_pid, audio_pid;
if (argc != 3) {
- printf ("\nusage: %s <video pid> <audio pid>\n\n", argv[0]);
+ printf ("\nusage: %s <video pid> <audio pid>\n\n" USAGE, argv[0]);
exit (1);
}
if (getenv("DEMUX"))
@@ -83,5 +84,3 @@ int main (int argc, char **argv)
return 0;
}
-
-
diff --git a/test/setvoltage.c b/test/setvoltage.c
index 1d14a4c..80f7688 100644
--- a/test/setvoltage.c
+++ b/test/setvoltage.c
@@ -1,10 +1,11 @@
-/*
- * Test switching the voltage signal high and low on a SAT frontend.
- * (Note: DiSEqC equipment ignores this after it has once seen a diseqc
- * sequence; reload the driver or unplug/replug the SAT cable to reset.)
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX setvoltage {13|18}
- */
+#define USAGE \
+"\n" \
+"\nTest switching the voltage signal high and low on a SAT frontend." \
+"\n(Note: DiSEqC equipment ignores this after it has once seen a diseqc" \
+"\n sequence; reload the driver or unplug/replug the SAT cable to reset.)" \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX setvoltage {13|18}" \
+"\n"
#include <stdlib.h>
#include <stdio.h>
@@ -23,7 +24,7 @@ int main (int argc, char **argv)
int fd, r;
if (argc != 2 || (strcmp(argv[1], "13") && strcmp(argv[1], "18"))) {
- fprintf (stderr, "usage: %s <13|18>\n", argv[0]);
+ fprintf (stderr, "usage: %s <13|18>\n" USAGE, argv[0]);
return -1;
}
if (getenv("FRONTEND"))
@@ -44,4 +45,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/test/szap2.c b/test/szap2.c
new file mode 100644
index 0000000..e470229
--- /dev/null
+++ b/test/szap2.c
@@ -0,0 +1,767 @@
+/* szap -- simple zapping tool for the Linux DVB API
+ *
+ * szap operates on VDR (http://www.cadsoft.de/people/kls/vdr/index.htm)
+ * satellite channel lists (e.g. from http://www.dxandy.de/cgi-bin/dvbchan.pl).
+ * szap assumes you have a "Universal LNB" (i.e. with LOFs 9750/10600 MHz).
+ *
+ * Compilation: `gcc -Wall -I../../ost/include -O2 szap.c -o szap`
+ * or, if your DVB driver is in the kernel source tree:
+ * `gcc -Wall -DDVB_IN_KERNEL -O2 szap.c -o szap`
+ *
+ * Copyright (C) 2001 Johannes Stezenbach (js@convergence.de)
+ * for convergence integrated media
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <stdint.h>
+#include <sys/time.h>
+
+#include "../include/frontend.h"
+#include "../include/dmx.h"
+#include "../include/audio.h"
+#include "../include/version.h"
+#include "lnb.h"
+
+#ifndef TRUE
+#define TRUE (1==1)
+#endif
+#ifndef FALSE
+#define FALSE (1==0)
+#endif
+
+/* location of channel list file */
+#define CHANNEL_FILE "channels.conf"
+
+/* one line of the VDR channel file has the following format:
+ * ^name:frequency_MHz:polarization:sat_no:symbolrate:vpid:apid:?:service_id$
+ */
+
+
+#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d"
+#define DEMUXDEVICE "/dev/dvb/adapter%d/demux%d"
+#define AUDIODEVICE "/dev/dvb/adapter%d/audio%d"
+
+static struct lnb_types_st lnb_type;
+
+static int exit_after_tuning;
+static int interactive;
+
+static char *usage_str =
+ "\nusage: szap -q\n"
+ " list known channels\n"
+ " szap [options] {-n channel-number|channel_name}\n"
+ " zap to channel via number or full name (case insensitive)\n"
+ " -a number : use given adapter (default 0)\n"
+ " -f number : use given frontend (default 0)\n"
+ " -d number : use given demux (default 0)\n"
+ " -c file : read channels list from 'file'\n"
+ " -b : enable Audio Bypass (default no)\n"
+ " -x : exit after tuning\n"
+ " -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n"
+ " -l lnb-type (DVB-S Only) (use -l help to print types) or \n"
+ " -l low[,high[,switch]] in Mhz\n"
+ " -i : run interactively, allowing you to type in channel names\n"
+ " -p : add pat and pmt to TS recording (implies -r)\n"
+ " or -n numbers for zapping\n"
+ " -t : delivery system type DVB-S=0, DSS=1, DVB-S2=2\n";
+
+static int set_demux(int dmxfd, int pid, int pes_type, int dvr)
+{
+ struct dmx_pes_filter_params pesfilter;
+
+ if (pid < 0 || pid >= 0x1fff) /* ignore this pid to allow radio services */
+ return TRUE;
+
+ if (dvr) {
+ int buffersize = 64 * 1024;
+ if (ioctl(dmxfd, DMX_SET_BUFFER_SIZE, buffersize) == -1)
+ perror("DMX_SET_BUFFER_SIZE failed");
+ }
+
+ pesfilter.pid = pid;
+ pesfilter.input = DMX_IN_FRONTEND;
+ pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER;
+ pesfilter.pes_type = pes_type;
+ pesfilter.flags = DMX_IMMEDIATE_START;
+
+ if (ioctl(dmxfd, DMX_SET_PES_FILTER, &pesfilter) == -1) {
+ fprintf(stderr, "DMX_SET_PES_FILTER failed "
+ "(PID = 0x%04x): %d %m\n", pid, errno);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int get_pmt_pid(char *dmxdev, int sid)
+{
+ int patfd, count;
+ int pmt_pid = 0;
+ int patread = 0;
+ int section_length;
+ unsigned char buft[4096];
+ unsigned char *buf = buft;
+ struct dmx_sct_filter_params f;
+
+ memset(&f, 0, sizeof(f));
+ f.pid = 0;
+ f.filter.filter[0] = 0x00;
+ f.filter.mask[0] = 0xff;
+ f.timeout = 0;
+ f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC;
+
+ if ((patfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("openening pat demux failed");
+ return -1;
+ }
+
+ if (ioctl(patfd, DMX_SET_FILTER, &f) == -1) {
+ perror("ioctl DMX_SET_FILTER failed");
+ close(patfd);
+ return -1;
+ }
+
+ while (!patread) {
+ if (((count = read(patfd, buf, sizeof(buft))) < 0) && errno == EOVERFLOW)
+ count = read(patfd, buf, sizeof(buft));
+ if (count < 0) {
+ perror("read_sections: read error");
+ close(patfd);
+ return -1;
+ }
+
+ section_length = ((buf[1] & 0x0f) << 8) | buf[2];
+ if (count != section_length + 3)
+ continue;
+
+ buf += 8;
+ section_length -= 8;
+
+ patread = 1; /* assumes one section contains the whole pat */
+ while (section_length > 0) {
+ int service_id = (buf[0] << 8) | buf[1];
+ if (service_id == sid) {
+ pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3];
+ section_length = 0;
+ }
+ buf += 4;
+ section_length -= 4;
+ }
+ }
+ close(patfd);
+ return pmt_pid;
+}
+
+struct diseqc_cmd {
+ struct dvb_diseqc_master_cmd cmd;
+ uint32_t wait;
+};
+
+void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
+ fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
+{
+ if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
+ perror("FE_SET_TONE failed");
+ if (ioctl(fd, FE_SET_VOLTAGE, v) == -1)
+ perror("FE_SET_VOLTAGE failed");
+ usleep(15 * 1000);
+ if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1)
+ perror("FE_DISEQC_SEND_MASTER_CMD failed");
+ usleep(cmd->wait * 1000);
+ usleep(15 * 1000);
+ if (ioctl(fd, FE_DISEQC_SEND_BURST, b) == -1)
+ perror("FE_DISEQC_SEND_BURST failed");
+ usleep(15 * 1000);
+ if (ioctl(fd, FE_SET_TONE, t) == -1)
+ perror("FE_SET_TONE failed");
+}
+
+
+
+
+/* digital satellite equipment control,
+ * specification is available from http://www.eutelsat.com/
+ */
+static int diseqc(int secfd, int sat_no, int pol_vert, int hi_band)
+{
+ struct diseqc_cmd cmd =
+ { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
+
+ /**
+ * param: high nibble: reset bits, low nibble set bits,
+ * bits are: option, position, polarizaion, band
+ */
+ cmd.cmd.msg[3] =
+ 0xf0 | (((sat_no * 4) & 0x0f) | (hi_band ? 1 : 0) | (pol_vert ? 0 : 2));
+
+ diseqc_send_msg(secfd, pol_vert ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18,
+ &cmd, hi_band ? SEC_TONE_ON : SEC_TONE_OFF,
+ (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
+
+ return TRUE;
+}
+
+#define DVBS 0
+#define DSS 1
+#define DVBS2 2
+
+static int do_tune(int fefd, unsigned int ifreq, unsigned int sr, unsigned int delsys)
+{
+ /* API Major=3, Minor=1 */
+ struct dvb_frontend_parameters tuneto;
+ struct dvb_frontend_event ev;
+ /* API Major=3, Minor=2 */
+ struct dvbfe_params fe_params;
+
+ /* discard stale QPSK events */
+ while (1) {
+ if (ioctl(fefd, FE_GET_EVENT, &ev) == -1)
+ break;
+ }
+
+ if ((DVB_API_VERSION == 3) && (DVB_API_VERSION_MINOR == 3)) {
+ printf("\n%s: API version=%d, delivery system = %d\n", __func__, DVB_API_VERSION_MINOR, delsys);
+
+ fe_params.frequency = ifreq;
+ fe_params.inversion = INVERSION_AUTO;
+
+ switch (delsys) {
+ case DVBS:
+ fe_params.delsys.dvbs.symbol_rate = sr;
+ fe_params.delsys.dvbs.fec = FEC_AUTO;
+ printf("%s: Frequency = %d, Srate = %d\n",
+ __func__, fe_params.frequency, fe_params.delsys.dvbs.symbol_rate);
+ break;
+ case DSS:
+ fe_params.delsys.dss.symbol_rate = sr;
+ fe_params.delsys.dss.fec = FEC_AUTO;
+ printf("%s: Frequency = %d, Srate = %d\n",
+ __func__, fe_params.frequency, fe_params.delsys.dss.symbol_rate);
+ break;
+ case DVBS2:
+ fe_params.delsys.dvbs2.symbol_rate = sr;
+ fe_params.delsys.dvbs2.fec = FEC_AUTO;
+ printf("%s: Frequency = %d, Srate = %d\n",
+ __func__, fe_params.frequency, fe_params.delsys.dvbs2.symbol_rate);
+ break;
+ default:
+ return -EINVAL;
+ }
+ printf("%s: Frequency = %d, Srate = %d\n\n\n",
+ __func__, fe_params.frequency, fe_params.delsys.dvbs.symbol_rate);
+
+ if (ioctl(fefd, DVBFE_SET_PARAMS, &fe_params) == -1) {
+ perror("DVBFE_SET_PARAMS failed");
+ return FALSE;
+ }
+
+ } else if ((DVB_API_VERSION == 3) && (DVB_API_VERSION_MINOR == 1)){
+ tuneto.frequency = ifreq;
+ tuneto.inversion = INVERSION_AUTO;
+ tuneto.u.qpsk.symbol_rate = sr;
+ tuneto.u.qpsk.fec_inner = FEC_AUTO;
+ if (ioctl(fefd, FE_SET_FRONTEND, &tuneto) == -1) {
+ perror("FE_SET_FRONTEND failed");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+static
+int check_frontend (int fe_fd, int dvr)
+{
+ (void)dvr;
+ fe_status_t status;
+ uint16_t snr, signal;
+ uint32_t ber, uncorrected_blocks;
+ int timeout = 0;
+
+ do {
+ if (ioctl(fe_fd, FE_READ_STATUS, &status) == -1)
+ perror("FE_READ_STATUS failed");
+ /* some frontends might not support all these ioctls, thus we
+ * avoid printing errors
+ */
+ if (ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1)
+ signal = -2;
+ if (ioctl(fe_fd, FE_READ_SNR, &snr) == -1)
+ snr = -2;
+ if (ioctl(fe_fd, FE_READ_BER, &ber) == -1)
+ ber = -2;
+ if (ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1)
+ uncorrected_blocks = -2;
+
+ printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
+ status, signal, snr, ber, uncorrected_blocks);
+
+ if (status & FE_HAS_LOCK)
+ printf("FE_HAS_LOCK");
+ printf("\n");
+
+ if (exit_after_tuning && ((status & FE_HAS_LOCK) || (++timeout >= 10)))
+ break;
+
+ usleep(1000000);
+ } while (1);
+
+ return 0;
+}
+
+
+static
+int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
+ unsigned int sat_no, unsigned int freq, unsigned int pol,
+ unsigned int sr, unsigned int vpid, unsigned int apid, int sid,
+ int dvr, int rec_psi, int bypass, unsigned int delsys)
+{
+ char fedev[128], dmxdev[128], auddev[128];
+ static int fefd, dmxfda, dmxfdv, audiofd = -1, patfd, pmtfd;
+ int pmtpid;
+ uint32_t ifreq;
+ int hiband, result;
+ enum dvbfe_delsys delivery;
+
+ switch (delsys) {
+ case DVBS:
+ printf("Delivery system=DVB-S\n");
+ delivery = DVBFE_DELSYS_DVBS;
+ break;
+ case DSS:
+ printf("Delivery system=DSS\n");
+ delivery = DVBFE_DELSYS_DSS;
+ break;
+ case DVBS2:
+ printf("Delivery system=DVB-S2\n");
+ delivery = DVBFE_DELSYS_DVBS2;
+ break;
+ default:
+ printf("Unsupported delivery system\n");
+ return -EINVAL;
+ }
+
+ if (!fefd) {
+ snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend);
+ snprintf(dmxdev, sizeof(dmxdev), DEMUXDEVICE, adapter, demux);
+ snprintf(auddev, sizeof(auddev), AUDIODEVICE, adapter, demux);
+ printf("using '%s' and '%s'\n", fedev, dmxdev);
+
+ if ((fefd = open(fedev, O_RDWR | O_NONBLOCK)) < 0) {
+ perror("opening frontend failed");
+ return FALSE;
+ }
+ result = ioctl(fefd, DVBFE_SET_DELSYS, &delivery);
+ if (result < 0) {
+ perror("ioctl DVBFE_SET_DELSYS failed");
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((dmxfdv = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening video demux failed");
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((dmxfda = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening audio demux failed");
+ close(fefd);
+ return FALSE;
+ }
+
+ if (dvr == 0) /* DMX_OUT_DECODER */
+ audiofd = open(auddev, O_RDWR);
+
+ if (rec_psi){
+ if ((patfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening pat demux failed");
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((pmtfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening pmt demux failed");
+ close(patfd);
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ return FALSE;
+ }
+ }
+ }
+
+ hiband = 0;
+ if (lnb_type.switch_val && lnb_type.high_val &&
+ freq >= lnb_type.switch_val)
+ hiband = 1;
+
+ if (hiband)
+ ifreq = freq - lnb_type.high_val;
+ else {
+ if (freq < lnb_type.low_val)
+ ifreq = lnb_type.low_val - freq;
+ else
+ ifreq = freq - lnb_type.low_val;
+ }
+ result = FALSE;
+
+ if (diseqc(fefd, sat_no, pol, hiband))
+ if (do_tune(fefd, ifreq, sr, delsys))
+ if (set_demux(dmxfdv, vpid, DMX_PES_VIDEO, dvr))
+ if (audiofd >= 0)
+ (void)ioctl(audiofd, AUDIO_SET_BYPASS_MODE, bypass);
+ if (set_demux(dmxfda, apid, DMX_PES_AUDIO, dvr)) {
+ if (rec_psi) {
+ pmtpid = get_pmt_pid(dmxdev, sid);
+ if (pmtpid < 0) {
+ result = FALSE;
+ }
+ if (pmtpid == 0) {
+ fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid);
+ result = FALSE;
+ }
+ if (set_demux(patfd, 0, DMX_PES_OTHER, dvr))
+ if (set_demux(pmtfd, pmtpid, DMX_PES_OTHER, dvr))
+ result = TRUE;
+ } else {
+ result = TRUE;
+ }
+ }
+
+ check_frontend (fefd, dvr);
+
+ if (!interactive) {
+ close(patfd);
+ close(pmtfd);
+ if (audiofd >= 0)
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ }
+
+ return result;
+}
+
+
+static int read_channels(const char *filename, int list_channels,
+ uint32_t chan_no, const char *chan_name,
+ unsigned int adapter, unsigned int frontend,
+ unsigned int demux, int dvr, int rec_psi,
+ int bypass, unsigned int delsys)
+{
+ FILE *cfp;
+ char buf[4096];
+ char inp[256];
+ char *field, *tmp, *p;
+ unsigned int line;
+ unsigned int freq, pol, sat_no, sr, vpid, apid, sid;
+ int ret;
+
+again:
+ line = 0;
+ if (!(cfp = fopen(filename, "r"))) {
+ fprintf(stderr, "error opening channel list '%s': %d %m\n",
+ filename, errno);
+ return FALSE;
+ }
+
+ if (interactive) {
+ fprintf(stderr, "\n>>> ");
+ if (!fgets(inp, sizeof(inp), stdin)) {
+ printf("\n");
+ return -1;
+ }
+ if (inp[0] == '-' && inp[1] == 'n') {
+ chan_no = strtoul(inp+2, NULL, 0);
+ chan_name = NULL;
+ if (!chan_no) {
+ fprintf(stderr, "bad channel number\n");
+ goto again;
+ }
+ } else {
+ p = strchr(inp, '\n');
+ if (p)
+ *p = '\0';
+ chan_name = inp;
+ chan_no = 0;
+ }
+ }
+
+ while (!feof(cfp)) {
+ if (fgets(buf, sizeof(buf), cfp)) {
+ line++;
+
+ if (chan_no && chan_no != line)
+ continue;
+
+ tmp = buf;
+ field = strsep(&tmp, ":");
+
+ if (!field)
+ goto syntax_err;
+
+ if (list_channels) {
+ printf("%03u %s\n", line, field);
+ continue;
+ }
+
+ if (chan_name && strcasecmp(chan_name, field) != 0)
+ continue;
+
+ printf("zapping to %d '%s':\n", line, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ freq = strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ pol = (field[0] == 'h' ? 0 : 1);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sat_no = strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sr = strtoul(field, NULL, 0) * 1000;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ vpid = strtoul(field, NULL, 0);
+ if (!vpid)
+ vpid = 0x1fff;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ p = strchr(field, ';');
+
+ if (p) {
+ *p = '\0';
+ p++;
+ if (bypass) {
+ if (!p || !*p)
+ goto syntax_err;
+ field = p;
+ }
+ }
+
+ apid = strtoul(field, NULL, 0);
+ if (!apid)
+ apid = 0x1fff;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sid = strtoul(field, NULL, 0);
+
+ printf("sat %u, frequency = %u MHz %c, symbolrate %u, "
+ "vpid = 0x%04x, apid = 0x%04x sid = 0x%04x\n",
+ sat_no, freq, pol ? 'V' : 'H', sr, vpid, apid, sid);
+
+ fclose(cfp);
+
+ ret = zap_to(adapter, frontend, demux, sat_no, freq * 1000,
+ pol, sr, vpid, apid, sid, dvr, rec_psi, bypass, delsys);
+ if (interactive)
+ goto again;
+
+ if (ret)
+ return TRUE;
+
+ return FALSE;
+
+syntax_err:
+ fprintf(stderr, "syntax error in line %u: '%s'\n", line, buf);
+ } else if (ferror(cfp)) {
+ fprintf(stderr, "error reading channel list '%s': %d %m\n",
+ filename, errno);
+ fclose(cfp);
+ return FALSE;
+ } else
+ break;
+ }
+
+ fclose(cfp);
+
+ if (!list_channels) {
+ fprintf(stderr, "channel not found\n");
+
+ if (!interactive)
+ return FALSE;
+ }
+ if (interactive)
+ goto again;
+
+ return TRUE;
+}
+
+
+void
+bad_usage(char *pname, int prlnb)
+{
+ int i;
+ struct lnb_types_st *lnbp;
+ char **cp;
+
+ if (!prlnb) {
+ fprintf (stderr, usage_str, pname);
+ } else {
+ i = 0;
+ fprintf(stderr, "-l <lnb-type> or -l low[,high[,switch]] in Mhz\nwhere <lnb-type> is:\n");
+ while(NULL != (lnbp = lnb_enum(i))) {
+ fprintf (stderr, "%s\n", lnbp->name);
+ for (cp = lnbp->desc; *cp ; cp++) {
+ fprintf (stderr, " %s\n", *cp);
+ }
+ i++;
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ const char *home;
+ char chanfile[2 * PATH_MAX];
+ int list_channels = 0;
+ unsigned int chan_no = 0;
+ const char *chan_name = NULL;
+ unsigned int adapter = 0, frontend = 0, demux = 0, dvr = 0, rec_psi = 0, delsys = 0;
+ int bypass = 0;
+ int opt, copt = 0;
+
+ lnb_type = *lnb_enum(0);
+ while ((opt = getopt(argc, argv, "hqrpn:a:f:d:t:c:l:xib")) != -1) {
+ switch (opt) {
+ case '?':
+ case 'h':
+ default:
+ bad_usage(argv[0], 0);
+ case 'b':
+ bypass = 1;
+ break;
+ case 'q':
+ list_channels = 1;
+ break;
+ case 'r':
+ dvr = 1;
+ break;
+ case 'n':
+ chan_no = strtoul(optarg, NULL, 0);
+ break;
+ case 'a':
+ adapter = strtoul(optarg, NULL, 0);
+ break;
+ case 'f':
+ frontend = strtoul(optarg, NULL, 0);
+ break;
+ case 'p':
+ rec_psi = 1;
+ break;
+ case 'd':
+ demux = strtoul(optarg, NULL, 0);
+ break;
+ case 't':
+ delsys = strtoul(optarg, NULL, 0);
+ break;
+ case 'c':
+ copt = 1;
+ strncpy(chanfile, optarg, sizeof(chanfile));
+ break;
+ case 'l':
+ if (lnb_decode(optarg, &lnb_type) < 0) {
+ bad_usage(argv[0], 1);
+ return -1;
+ }
+ break;
+ case 'x':
+ exit_after_tuning = 1;
+ break;
+ case 'i':
+ interactive = 1;
+ exit_after_tuning = 1;
+ }
+ }
+ lnb_type.low_val *= 1000; /* convert to kiloherz */
+ lnb_type.high_val *= 1000; /* convert to kiloherz */
+ lnb_type.switch_val *= 1000; /* convert to kiloherz */
+ if (optind < argc)
+ chan_name = argv[optind];
+ if (chan_name && chan_no) {
+ bad_usage(argv[0], 0);
+ return -1;
+ }
+ if (list_channels && (chan_name || chan_no)) {
+ bad_usage(argv[0], 0);
+ return -1;
+ }
+ if (!list_channels && !chan_name && !chan_no && !interactive) {
+ bad_usage(argv[0], 0);
+ return -1;
+ }
+
+ if (!copt) {
+ if (!(home = getenv("HOME"))) {
+ fprintf(stderr, "error: $HOME not set\n");
+ return TRUE;
+ }
+ snprintf(chanfile, sizeof(chanfile),
+ "%s/.szap/%i/%s", home, adapter, CHANNEL_FILE);
+ if (access(chanfile, R_OK))
+ snprintf(chanfile, sizeof(chanfile),
+ "%s/.szap/%s", home, CHANNEL_FILE);
+ }
+
+ printf("reading channels from file '%s'\n", chanfile);
+
+ if (rec_psi)
+ dvr=1;
+
+ if (!read_channels(chanfile, list_channels, chan_no, chan_name,
+ adapter, frontend, demux, dvr, rec_psi, bypass, delsys))
+
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/test/test.c b/test/test.c
index 6c9af51..2881a7a 100644
--- a/test/test.c
+++ b/test/test.c
@@ -1,4 +1,4 @@
-/*
+/*
* test.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -58,7 +58,7 @@ inline t2a(uint8_t c)
c=reverse[c]&0x7f;
if (c<0x20)
c=0x20;
-
+
return c;
}
@@ -68,16 +68,16 @@ void testpesfilter(void)
int i,j;
int len;
int fd=open("/dev/ost/demux1", O_RDWR);
- struct dmx_pes_filter_params pesFilterParams;
-
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_TS_TAP;
- pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ struct dmx_pes_filter_params pesFilterParams;
+
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
-
+
pesFilterParams.pid = 0x2c ;
if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
- printf("Could not set PES filter\n");
+ printf("Could not set PES filter\n");
close(fd);
return;
}
@@ -85,7 +85,7 @@ void testpesfilter(void)
/*
pesFilterParams.pid = 54;
if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
- printf("Could not set PES filter\n");
+ printf("Could not set PES filter\n");
close(fd);
return;
}
@@ -93,7 +93,7 @@ void testpesfilter(void)
pesFilterParams.pid = 55;
if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
- printf("Could not set PES filter\n");
+ printf("Could not set PES filter\n");
close(fd);
return;
}
@@ -103,7 +103,7 @@ void testpesfilter(void)
if (len>0) write(1, buf, len);
}
- do {
+ do {
read(fd, buf, 4);
if (htonl(*(uint32_t *)buf)!=0x00001bd)
continue;
@@ -112,10 +112,10 @@ void testpesfilter(void)
read(fd, buf+6, len);
fprintf(stderr,"read %d bytes PES\n", len);
write (1, buf, len+6);
-
+
id=buf[45];
fprintf(stderr,"id=%02x\n", id);
-
+
for (i=0; i<(len+6-46)/46; i++) {
for (j=6; j<46; j++) {
fprintf(stderr,"%c", t2a(buf[i*46+46+j]));
@@ -128,11 +128,11 @@ void testpesfilter(void)
/*
pesFilterParams.pid = 55;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
-
+
ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams);
close(fd);
*/
@@ -145,8 +145,8 @@ senf()
int len;
struct secCommand scmd;
struct secCmdSequence scmds;
- struct dmx_pes_filter_params pesFilterParams;
- struct dmx_sct_filter_params secFilterParams;
+ struct dmx_pes_filter_params pesFilterParams;
+ struct dmx_sct_filter_params secFilterParams;
FrontendParameters frp;
uint8_t buf[4096];
@@ -173,7 +173,7 @@ senf()
scmd.u.diseqc.cmd=0x38;
scmd.u.diseqc.numParams=1;
scmd.u.diseqc.params[0]=0xf0;
-
+
scmds.voltage=SEC_VOLTAGE_13;
scmds.miniCommand=SEC_MINI_NONE;
scmds.continuousTone=SEC_TONE_ON;
@@ -195,31 +195,31 @@ senf()
if (ret<0)
perror("DMX_SET_BUFFER_SIZE\n");
printf("Audio filter size OK\n");
- pesFilterParams.pid = 0x60;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_AUDIO;
+ pesFilterParams.pid = 0x60;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_AUDIO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
-
- if (ioctl(fd_demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
+
+ if (ioctl(fd_demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
printf("Audio filter OK\n");
-
- if (ioctl(fd_demux, DMX_SET_BUFFER_SIZE, 64*1024) < 0) return(1);
+
+ if (ioctl(fd_demux, DMX_SET_BUFFER_SIZE, 64*1024) < 0) return(1);
pesFilterParams.pid = 0xa2;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_VIDEO;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_VIDEO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demux, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
+ if (ioctl(fd_demux, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
printf("Video filter OK\n");
#endif
/*
pesFilterParams.pid = 56;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_tt, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
+ if (ioctl(fd_tt, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
printf("TT filter OK\n");
*/
//while (1);
@@ -250,7 +250,7 @@ senf()
int32_t snr, str;
ioctl(fd_frontend, FE_READ_SNR, &snr);
ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &str);
-
+
printf("snr=%d, str=%d\n", snr, str);
}
*/
@@ -260,7 +260,7 @@ senf()
if (ioctl(fd_section, DMX_SET_FILTER, &secFilterParams) < 0) return;
//if (ioctl(fd_section2, DMX_SET_FILTER, &secFilterParams) < 0) return;
//close(fd_section2);
- //while (1)
+ //while (1)
{
len=read(fd_section, buf, 4096);
if (len>0) write(1, buf, len);
@@ -270,7 +270,7 @@ senf()
//if (len>0) write(1,buf,len);
//printf("read section with length %d\n", len);
}
-
+
}
main()
@@ -278,4 +278,3 @@ main()
//senf();
testpesfilter();
}
-
diff --git a/test/test_audio.c b/test/test_audio.c
index 0abb734..f7bfacc 100644
--- a/test/test_audio.c
+++ b/test/test_audio.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_audio.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -40,7 +40,7 @@ int audioStop(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_STOP,0) < 0)){
+ if ((ans = ioctl(fd,AUDIO_STOP,0)) < 0) {
perror("AUDIO STOP: ");
return -1;
}
@@ -52,7 +52,7 @@ int audioPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){
+ if ((ans = ioctl(fd,AUDIO_PLAY)) < 0) {
perror("AUDIO PLAY: ");
return -1;
}
@@ -65,7 +65,7 @@ int audioPause(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_PAUSE) < 0)){
+ if ((ans = ioctl(fd,AUDIO_PAUSE)) < 0) {
perror("AUDIO PAUSE: ");
return -1;
}
@@ -78,7 +78,7 @@ int audioContinue(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_CONTINUE) < 0)){
+ if ((ans = ioctl(fd,AUDIO_CONTINUE)) < 0) {
perror("AUDIO CONTINUE: ");
return -1;
}
@@ -90,7 +90,7 @@ int audioSelectSource(int fd, audio_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SELECT_SOURCE, source)) < 0) {
perror("AUDIO SELECT SOURCE: ");
return -1;
}
@@ -104,7 +104,7 @@ int audioSetMute(int fd, boolean state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_MUTE, state)) < 0) {
perror("AUDIO SET MUTE: ");
return -1;
}
@@ -116,7 +116,7 @@ int audioSetAVSync(int fd,boolean state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_AV_SYNC, state)) < 0) {
perror("AUDIO SET AV SYNC: ");
return -1;
}
@@ -128,8 +128,8 @@ int audioSetBypassMode(int fd,boolean mode)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_BYPASS_MODE, mode) < 0)){
- perror("AUDIO SET BYPASS MODE: ");
+ if ((ans = ioctl(fd,AUDIO_SET_BYPASS_MODE, mode)) < 0) {
+ printf("AUDIO SET BYPASS MODE not implemented?\n");
return -1;
}
@@ -141,7 +141,7 @@ int audioChannelSelect(int fd, audio_channel_select_t select)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_CHANNEL_SELECT, select) < 0)){
+ if ((ans = ioctl(fd,AUDIO_CHANNEL_SELECT, select)) < 0) {
perror("AUDIO CHANNEL SELECT: ");
return -1;
}
@@ -154,7 +154,7 @@ int audioGetStatus(int fd)
struct audio_status stat;
int ans;
- if ( (ans = ioctl(fd,AUDIO_GET_STATUS, &stat) < 0)){
+ if ((ans = ioctl(fd,AUDIO_GET_STATUS, &stat)) < 0) {
perror("AUDIO GET STATUS: ");
return -1;
}
@@ -179,7 +179,7 @@ int audioGetStatus(int fd)
printf("unknown (%d)\n",stat.play_state);
break;
}
-
+
printf(" Stream Source : ");
switch((int)stat.stream_source){
case AUDIO_SOURCE_DEMUX:
@@ -227,7 +227,7 @@ play_file_audio(int filefd, int fd)
int stopped = 0;
boolean mute = false;
boolean sync = false;
-
+
pfd[0].fd = STDIN_FILENO;
pfd[0].events = POLLIN;
@@ -257,7 +257,7 @@ play_file_audio(int filefd, int fd)
printf("playback stopped\n");
stopped = 1;
break;
-
+
case 'c':
audioContinue(fd);
printf("playback continued\n");
@@ -291,7 +291,7 @@ play_file_audio(int filefd, int fd)
break;
}
}
-
+
}
}
}
@@ -312,8 +312,8 @@ main(int argc, char **argv)
perror("File open:");
return -1;
}
-
- if((fd = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){
+
+ if ((fd = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){
perror("AUDIO DEVICE: ");
return -1;
}
@@ -321,7 +321,7 @@ main(int argc, char **argv)
audioSetMute(fd,mute);
- // audioSetBypassMode(fd,false); // not implemented
+ audioSetBypassMode(fd,false);
//audioContinue(fd);
audioSelectSource(fd,AUDIO_SOURCE_MEMORY);
audioPlay(fd);
@@ -334,7 +334,7 @@ main(int argc, char **argv)
//audioChannelSelect(fd,AUDIO_STEREO);
//audioSetAVSync(fd,sync);
audioGetStatus(fd);
-
+
play_file_audio(filefd,fd);
close(fd);
@@ -342,4 +342,3 @@ main(int argc, char **argv)
}
-
diff --git a/test/test_av.c b/test/test_av.c
index 5d77000..6c32848 100644
--- a/test/test_av.c
+++ b/test/test_av.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_av.c - Test for audio and video MPEG decoder API.
*
* Copyright (C) 2000 - 2002 convergence GmbH
@@ -30,6 +30,7 @@
#include <time.h>
#include <unistd.h>
+#include <linux/types.h>
#include <linux/dvb/audio.h>
#include <linux/dvb/video.h>
@@ -94,11 +95,11 @@ int audioSetMute(int fd, char *arg)
int audioSetAVSync(int fd, char *arg)
{
- int sync;
+ int _sync;
if (!arg)
return -1;
- sync = atoi(arg);
- if (ioctl(fd, AUDIO_SET_AV_SYNC, sync) == -1)
+ _sync = atoi(arg);
+ if (ioctl(fd, AUDIO_SET_AV_SYNC, _sync) == -1)
perror("AUDIO_SET_AV_SYNC");
return 0;
}
@@ -127,66 +128,66 @@ int audioChannelSelect(int fd, char *arg)
int audioGetStatus(int fd, char *arg)
{
- struct audio_status stat;
+ struct audio_status _stat;
if (arg)
return -1;
- if (ioctl(fd, AUDIO_GET_STATUS, &stat) == -1) {
+ if (ioctl(fd, AUDIO_GET_STATUS, &_stat) == -1) {
perror("AUDIO_GET_STATUS");
return 0;
}
printf("Audio Status:\n");
printf(" Sync State : %s\n",
- (stat.AV_sync_state ? "SYNC" : "NO SYNC"));
+ (_stat.AV_sync_state ? "SYNC" : "NO SYNC"));
printf(" Mute State : %s\n",
- (stat.mute_state ? "muted" : "not muted"));
+ (_stat.mute_state ? "muted" : "not muted"));
printf(" Play State : ");
- switch ((int)stat.play_state){
+ switch ((int)_stat.play_state){
case AUDIO_STOPPED:
- printf("STOPPED (%d)\n",stat.play_state);
+ printf("STOPPED (%d)\n",_stat.play_state);
break;
case AUDIO_PLAYING:
- printf("PLAYING (%d)\n",stat.play_state);
+ printf("PLAYING (%d)\n",_stat.play_state);
break;
case AUDIO_PAUSED:
- printf("PAUSED (%d)\n",stat.play_state);
+ printf("PAUSED (%d)\n",_stat.play_state);
break;
default:
- printf("unknown (%d)\n",stat.play_state);
+ printf("unknown (%d)\n",_stat.play_state);
break;
}
printf(" Stream Source : ");
- switch((int)stat.stream_source){
+ switch((int)_stat.stream_source){
case AUDIO_SOURCE_DEMUX:
- printf("DEMUX (%d)\n",stat.stream_source);
+ printf("DEMUX (%d)\n",_stat.stream_source);
break;
case AUDIO_SOURCE_MEMORY:
- printf("MEMORY (%d)\n",stat.stream_source);
+ printf("MEMORY (%d)\n",_stat.stream_source);
break;
default:
- printf("unknown (%d)\n",stat.stream_source);
+ printf("unknown (%d)\n",_stat.stream_source);
break;
}
printf(" Channel Select : ");
- switch((int)stat.channel_select){
+ switch((int)_stat.channel_select){
case AUDIO_STEREO:
- printf("Stereo (%d)\n",stat.channel_select);
+ printf("Stereo (%d)\n",_stat.channel_select);
break;
case AUDIO_MONO_LEFT:
- printf("Mono left(%d)\n",stat.channel_select);
+ printf("Mono left(%d)\n",_stat.channel_select);
break;
case AUDIO_MONO_RIGHT:
- printf("Mono right (%d)\n",stat.channel_select);
+ printf("Mono right (%d)\n",_stat.channel_select);
break;
default:
- printf("unknown (%d)\n",stat.channel_select);
+ printf("unknown (%d)\n",_stat.channel_select);
break;
}
printf(" Bypass Mode : %s\n",
- (stat.bypass_mode ? "ON" : "OFF"));
+ (_stat.bypass_mode ? "ON" : "OFF"));
return 0;
@@ -300,76 +301,76 @@ int videoSlowMotion(int fd, char *arg)
int videoGetStatus(int fd, char *arg)
{
- struct video_status stat;
+ struct video_status _stat;
if (arg)
return -1;
- if (ioctl(fd, VIDEO_GET_STATUS, &stat) == -1){
+ if (ioctl(fd, VIDEO_GET_STATUS, &_stat) == -1){
perror("VIDEO_GET_STATUS");
return 0;
}
printf("Video Status:\n");
printf(" Blank State : %s\n",
- (stat.video_blank ? "BLANK" : "STILL"));
+ (_stat.video_blank ? "BLANK" : "STILL"));
printf(" Play State : ");
- switch ((int)stat.play_state){
+ switch ((int)_stat.play_state){
case VIDEO_STOPPED:
- printf("STOPPED (%d)\n",stat.play_state);
+ printf("STOPPED (%d)\n",_stat.play_state);
break;
case VIDEO_PLAYING:
- printf("PLAYING (%d)\n",stat.play_state);
+ printf("PLAYING (%d)\n",_stat.play_state);
break;
case VIDEO_FREEZED:
- printf("FREEZED (%d)\n",stat.play_state);
+ printf("FREEZED (%d)\n",_stat.play_state);
break;
default:
- printf("unknown (%d)\n",stat.play_state);
+ printf("unknown (%d)\n",_stat.play_state);
break;
}
printf(" Stream Source : ");
- switch((int)stat.stream_source){
+ switch((int)_stat.stream_source){
case VIDEO_SOURCE_DEMUX:
- printf("DEMUX (%d)\n",stat.stream_source);
+ printf("DEMUX (%d)\n",_stat.stream_source);
break;
case VIDEO_SOURCE_MEMORY:
- printf("MEMORY (%d)\n",stat.stream_source);
+ printf("MEMORY (%d)\n",_stat.stream_source);
break;
default:
- printf("unknown (%d)\n",stat.stream_source);
+ printf("unknown (%d)\n",_stat.stream_source);
break;
}
printf(" Format (Aspect Ratio): ");
- switch((int)stat.video_format){
+ switch((int)_stat.video_format){
case VIDEO_FORMAT_4_3:
- printf("4:3 (%d)\n",stat.video_format);
+ printf("4:3 (%d)\n",_stat.video_format);
break;
case VIDEO_FORMAT_16_9:
- printf("16:9 (%d)\n",stat.video_format);
+ printf("16:9 (%d)\n",_stat.video_format);
break;
case VIDEO_FORMAT_221_1:
- printf("2.21:1 (%d)\n",stat.video_format);
+ printf("2.21:1 (%d)\n",_stat.video_format);
break;
default:
- printf("unknown (%d)\n",stat.video_format);
+ printf("unknown (%d)\n",_stat.video_format);
break;
}
printf(" Display Format : ");
- switch((int)stat.display_format){
+ switch((int)_stat.display_format){
case VIDEO_PAN_SCAN:
- printf("Pan&Scan (%d)\n",stat.display_format);
+ printf("Pan&Scan (%d)\n",_stat.display_format);
break;
case VIDEO_LETTER_BOX:
- printf("Letterbox (%d)\n",stat.display_format);
+ printf("Letterbox (%d)\n",_stat.display_format);
break;
case VIDEO_CENTER_CUT_OUT:
- printf("Center cutout (%d)\n",stat.display_format);
+ printf("Center cutout (%d)\n",_stat.display_format);
break;
default:
- printf("unknown (%d)\n",stat.display_format);
+ printf("unknown (%d)\n",_stat.display_format);
break;
}
return 0;
@@ -424,12 +425,12 @@ int videoStillPicture(int fd, char *arg)
sp.size = st.st_size;
printf("I-frame size: %d\n", sp.size);
- if(!sp.iFrame) {
+ if (!sp.iFrame) {
printf("No memory for I-Frame\n");
return 0;
}
- printf("read: %d bytes\n",read(sifd,sp.iFrame,sp.size));
+ printf("read: %d bytes\n", (int) read(sifd,sp.iFrame,sp.size));
if (ioctl(fd, VIDEO_STILLPICTURE, &sp) == -1)
perror("VIDEO_STILLPICTURE");
return 0;
@@ -555,11 +556,11 @@ int main(void)
printf("using audio device '%s'\n", audiodev);
printf("enter command or h + enter for help\n");
- if((vfd = open(videodev, O_RDWR | O_NONBLOCK)) < 0) {
+ if ((vfd = open(videodev, O_RDWR | O_NONBLOCK)) < 0) {
perror("open video device");
return 1;
}
- if((afd = open(audiodev, O_RDWR | O_NONBLOCK)) < 0) {
+ if ((afd = open(audiodev, O_RDWR | O_NONBLOCK)) < 0) {
perror("open audio device");
return 1;
}
@@ -571,4 +572,3 @@ int main(void)
close(afd);
return 0;
}
-
diff --git a/test/test_av_play.c b/test/test_av_play.c
index 293d6d8..b7ad867 100644
--- a/test/test_av_play.c
+++ b/test/test_av_play.c
@@ -19,27 +19,44 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * Thu Jun 24 09:18:44 CEST 2004
+ * Add scan_file_av() and copy_to_dvb() for AV
+ * filtering to be able to use AC3 audio streams
+ * Copyright (C) 2004 Werner Fink <werner@suse.de>
*/
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
#include <sys/ioctl.h>
#include <stdio.h>
+#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <netinet/in.h>
#include <fcntl.h>
#include <time.h>
+#include <termios.h>
#include <unistd.h>
+#include <errno.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <sys/poll.h>
+static char dolby;
+static char audio;
+static char black;
+static char volset;
+
static int audioPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){
+ if ((ans = ioctl(fd,AUDIO_PLAY)) < 0) {
perror("AUDIO PLAY: ");
return -1;
}
@@ -47,12 +64,11 @@ static int audioPlay(int fd)
return 0;
}
-
static int audioSelectSource(int fd, audio_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SELECT_SOURCE, source)) < 0) {
perror("AUDIO SELECT SOURCE: ");
return -1;
}
@@ -60,13 +76,11 @@ static int audioSelectSource(int fd, audio_stream_source_t source)
return 0;
}
-
-
static int audioSetMute(int fd, int state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_MUTE, state)) < 0) {
perror("AUDIO SET MUTE: ");
return -1;
}
@@ -78,7 +92,7 @@ static int audioSetAVSync(int fd, int state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_AV_SYNC, state)) < 0) {
perror("AUDIO SET AV SYNC: ");
return -1;
}
@@ -86,11 +100,55 @@ static int audioSetAVSync(int fd, int state)
return 0;
}
+static int audioSetVolume(int fd, int level)
+{
+ int ans;
+ audio_mixer_t mix;
+
+ mix.volume_left = mix.volume_right = level;
+ if ((ans = ioctl(fd, AUDIO_SET_MIXER, &mix)) < 0) {
+ perror("AUDIO SET VOLUME: ");
+ return -1;
+ }
+ return 0;
+}
+
+static int audioStop(int fd)
+{
+ int ans;
+
+ if ((ans = ioctl(fd,AUDIO_STOP,0)) < 0) {
+ perror("AUDIO STOP: ");
+ return -1;
+ }
+ return 0;
+}
+
+static int deviceClear(int afd, int vfd)
+{
+ int ans;
+
+ if (vfd >= 0) {
+ if ((ans = ioctl(vfd, VIDEO_CLEAR_BUFFER, 0)) < 0) {
+ perror("VIDEO CLEAR BUFFER: ");
+ return -1;
+ }
+ }
+ if (afd >= 0) {
+ if ((ans = ioctl(afd, AUDIO_CLEAR_BUFFER, 0)) < 0) {
+ perror("AUDIO CLEAR BUFFER: ");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static int videoStop(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){
+ if ((ans = ioctl(fd,VIDEO_STOP,0)) < 0) {
perror("VIDEO STOP: ");
return -1;
}
@@ -102,7 +160,7 @@ static int videoPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){
+ if ((ans = ioctl(fd,VIDEO_PLAY)) < 0) {
perror("VIDEO PLAY: ");
return -1;
}
@@ -110,12 +168,11 @@ static int videoPlay(int fd)
return 0;
}
-
static int videoFreeze(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FREEZE)) < 0) {
perror("VIDEO FREEZE: ");
return -1;
}
@@ -123,12 +180,22 @@ static int videoFreeze(int fd)
return 0;
}
+static int videoBlank(int fd, int state)
+{
+ int ans;
+
+ if ((ans = ioctl(fd, VIDEO_SET_BLANK, state)) < 0) {
+ perror("VIDEO BLANK: ");
+ return -1;
+ }
+ return 0;
+}
static int videoContinue(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_CONTINUE)) < 0) {
perror("VIDEO CONTINUE: ");
return -1;
}
@@ -140,7 +207,7 @@ static int videoSelectSource(int fd, video_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SELECT_SOURCE, source)) < 0) {
perror("VIDEO SELECT SOURCE: ");
return -1;
}
@@ -153,7 +220,7 @@ static int videoFastForward(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes)) < 0) {
perror("VIDEO FAST FORWARD: ");
return -1;
}
@@ -165,7 +232,7 @@ static int videoSlowMotion(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SLOWMOTION, nframes)) < 0) {
perror("VIDEO SLOWMOTION: ");
return -1;
}
@@ -173,14 +240,11 @@ static int videoSlowMotion(int fd,int nframes)
return 0;
}
-#define BUFFY 32768
-#define NFD 2
-static void play_file_av(int filefd, int vfd, int afd)
+#define NFD 3
+static void copy_to_dvb(int vfd, int afd, int cfd, const uint8_t* ptr, const unsigned short len)
{
- char buf[BUFFY];
- int count;
- int written;
struct pollfd pfd[NFD];
+ unsigned short pos = 0;
int stopped = 0;
pfd[0].fd = STDIN_FILENO;
@@ -192,119 +256,399 @@ static void play_file_av(int filefd, int vfd, int afd)
pfd[2].fd = afd;
pfd[2].events = POLLOUT;
- videoSelectSource(vfd,VIDEO_SOURCE_MEMORY);
- audioSelectSource(afd,AUDIO_SOURCE_MEMORY);
-
- // FIXME: only seems to work if starting audio first!
- audioPlay(afd);
- videoPlay(vfd);
-
- count = read(filefd,buf,BUFFY);
- write(vfd,buf,count);
-
- while ( (count = read(filefd,buf,BUFFY)) >= 0 ){
- written = 0;
- while(written < count){
- if (poll(pfd,NFD,1)){
- if (pfd[1].revents & POLLOUT){
- written += write(vfd,buf+written,
- count-written);
+ while (pos < len) {
+ int ret;
+ if ((ret = poll(pfd,NFD,1)) > 0) {
+ if (pfd[1].revents & POLLOUT) {
+ int cnt = write(cfd, ptr + pos, len - pos);
+ if (cnt > 0)
+ pos += cnt;
+ else if (cnt < 0) {
+ if (errno != EAGAIN && errno != EINTR) {
+ perror("Write:");
+ exit(-1);
+ }
+ if (errno == EAGAIN)
+ usleep(1000);
+ continue;
}
- if (pfd[0].revents & POLLIN){
- int c = getchar();
- switch(c){
- case 'z':
+ }
+ if (pfd[0].revents & POLLIN) {
+ int c = getchar();
+ switch(c) {
+ case 'z':
+ if (audio && !black) {
+ audioSetMute(afd, 1);
+ } else {
videoFreeze(vfd);
- printf("playback frozen\n");
- stopped = 1;
- break;
-
- case 's':
+ }
+ deviceClear(afd, -1);
+ printf("playback frozen\n");
+ stopped = 1;
+ break;
+
+ case 's':
+ if (audio) {
+ audioStop(afd);
+ deviceClear(afd, -1);
+ } else {
videoStop(vfd);
- printf("playback stopped\n");
- stopped = 1;
- break;
-
- case 'c':
+ deviceClear(afd, vfd);
+ }
+ printf("playback stopped\n");
+ stopped = 1;
+ break;
+
+ case 'c':
+ if (audio && !black) {
+ audioSetAVSync(afd, 0);
+ deviceClear(afd, -1);
+ audioSetMute(afd, 0);
+ } else {
+ audioSetAVSync(afd, 1);
+ deviceClear(afd, vfd);
videoContinue(vfd);
- printf("playback continued\n");
- stopped = 0;
- break;
-
- case 'p':
- videoPlay(vfd);
+ }
+ printf("playback continued\n");
+ stopped = 0;
+ break;
+
+ case 'p':
+ if (audio) {
+ deviceClear(afd, -1);
+ audioSetAVSync(afd, 0);
audioPlay(afd);
- audioSetAVSync(afd, 1);
- audioSetMute(afd, 0);
- printf("playback started\n");
- stopped = 0;
- break;
-
- case 'f':
- audioSetAVSync(afd, 0);
+ } else {
+ deviceClear(afd, vfd);
+ audioSetAVSync(afd, 1);
+ audioPlay(afd);
+ videoPlay(vfd);
+ }
+ audioSetMute(afd, 0);
+ printf("playback started\n");
+ stopped = 0;
+ break;
+
+ case 'f':
+ audioSetAVSync(afd, 0);
+ if (!audio) {
audioSetMute(afd, 1);
videoFastForward(vfd,0);
- printf("fastforward\n");
- stopped = 0;
- break;
-
- case 'm':
- audioSetAVSync(afd, 0);
+ }
+ printf("fastforward\n");
+ stopped = 0;
+ break;
+
+ case 'm':
+ audioSetAVSync(afd, 0);
+ audioSetMute(afd, 1);
+ printf("mute\n");
+ stopped = 0;
+ break;
+
+ case 'u':
+ audioSetAVSync(afd, 1);
+ audioSetMute(afd, 0);
+ printf("unmute\n");
+ stopped = 0;
+ break;
+
+ case 'd':
+ if (dolby)
+ dolby = 0;
+ else
+ dolby++;
+ break;
+
+ case 'l':
+ audioSetAVSync(afd, 0);
+ if (!audio) {
audioSetMute(afd, 1);
videoSlowMotion(vfd,2);
- printf("slowmotion\n");
- stopped = 0;
- break;
+ }
+ printf("slowmotion\n");
+ stopped = 0;
+ break;
- case 'q':
- videoContinue(vfd);
- exit(0);
+ case 'q':
+ videoContinue(vfd);
+ exit(0);
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (ret < 0) {
+ if (errno != EAGAIN && errno != EINTR) {
+ perror("Write:");
+ exit(-1);
+ }
+ if (errno == EAGAIN)
+ usleep(1000);
+ }
+ }
+}
+
+static unsigned char play[6] = {0x00, 0x00, 0x01, 0xff, 0xff, 0xff};
+static unsigned char except[2];
+
+static int scan_file_av(int vfd, int afd, const unsigned char *buf, int buflen)
+{
+ const unsigned char *const start = buf;
+ const unsigned char *const end = buf + buflen;
+
+ static unsigned int magic = 0xffffffff;
+ static unsigned short count, len;
+ static int fdc = -1;
+ int m;
+
+ while (buf < end) {
+ if (count < 6) {
+ switch (count) {
+ case 0:
+ m = 0;
+ while ((magic & 0xffffff00) != 0x00000100) {
+ if (buf >= end) goto out;
+ magic = (magic << 8) | *buf++;
+ m++;
+ }
+ if (m > 4)
+ printf("Broken Frame found\n");
+ play[3] = (unsigned char)(magic & 0x000000ff);
+ switch (play[3]) {
+ case 0xE0 ... 0xEF:
+ fdc = vfd;
+ if (except[0] != play[3]) {
+ if (except[0] == 0)
+ except[0] = play[3];
+ else
+ fdc = -1;
+ }
+ if (audio)
+ fdc = -1;
+ break;
+ case 0xC0 ... 0xDF:
+ fdc = afd;
+ if (dolby) {
+ fdc = -1;
break;
}
+ if (except[1] != play[3]) {
+ if (except[1] == 0)
+ except[1] = play[3];
+ else
+ fdc = -1;
+ }
+ if (!volset) {
+ audioSetVolume(afd, 255);
+ volset = 1;
+ }
+ break;
+ case 0xBD:
+ /*
+ * TODO: sub filter to through out e.g. ub pictures
+ * in Private Streams 1 _and_ get sub audio header
+ * to set an except(ion) audio stream.
+ * The later one requires some changes within the VDR
+ * remux part! 2004/07/01 Werner
+ */
+ fdc = afd;
+ if (!dolby) {
+ fdc = -1;
+ break;
+ }
+ if (volset) {
+ audioSetVolume(afd, 0);
+ volset = 0;
+ }
+ break;
+ default:
+ fdc = -1;
+ break;
}
+ count = 4;
+ case 4:
+ if (buf >= end) goto out;
+ len = ((*buf) << 8);
+ play[4] = (*buf);
+ buf++;
+ count++;
+ case 5:
+ if (buf >= end) goto out;
+ len |= (*buf);
+ len += 6;
+ play[5] = (*buf);
+ buf++;
+ count++;
+ if (fdc != -1)
+ copy_to_dvb(vfd, afd, fdc, &play[0], count);
+ default:
+ break;
}
}
+
+ while (count < len) {
+ int rest = end - buf;
+ if (rest <= 0) goto out;
+
+ if (rest + count > len)
+ rest = len - count;
+
+ if (fdc != -1)
+ copy_to_dvb(vfd, afd, fdc, buf, rest);
+ count += rest;
+ buf += rest;
+ }
+
+ /* Reset for next scan */
+ magic = 0xffffffff;
+ count = len = 0;
+ fdc = -1;
+ play[3] = 0xff;
}
+out:
+ return buf - start;
+}
+
+#define BUFFY 32768
+static void play_file_av(int filefd, int vfd, int afd)
+{
+ unsigned char buf[BUFFY];
+ int count;
+
+ audioSetMute(afd, 1);
+ videoBlank(vfd, 1);
+ if (audio && !black) {
+ audioStop(afd);
+ deviceClear(afd, -1);
+ audioSetAVSync(afd, 0);
+ audioSelectSource(afd, AUDIO_SOURCE_MEMORY);
+ audioPlay(afd);
+ videoBlank(vfd, 0);
+ } else if (audio && black) {
+ deviceClear(afd, vfd);
+ videoBlank(vfd, 1);
+ audioSetAVSync(afd, 0);
+ audioSelectSource(afd, AUDIO_SOURCE_MEMORY);
+ videoSelectSource(vfd, VIDEO_SOURCE_MEMORY);
+ audioPlay(afd);
+ videoPlay(vfd);
+ } else {
+ deviceClear(afd, vfd);
+ audioSetAVSync(afd, 1);
+ audioSelectSource(afd, AUDIO_SOURCE_MEMORY);
+ videoSelectSource(vfd, VIDEO_SOURCE_MEMORY);
+ audioPlay(afd);
+ videoPlay(vfd);
+ videoBlank(vfd, 0);
+ }
+
+ if (dolby) {
+ audioSetVolume(afd, 0);
+ volset = 0;
+ } else {
+ audioSetVolume(afd, 255);
+ volset = 1;
+ }
+
+#ifndef __stub_posix_fadvise
+ posix_fadvise(filefd, 0, 0, POSIX_FADV_SEQUENTIAL);
+#endif
+
+ while ((count = read(filefd,buf,BUFFY)) > 0)
+ scan_file_av(vfd,afd,buf,count);
+}
+
+static struct termios term;
+
+static void restore(void)
+{
+ tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
int main(int argc, char **argv)
{
- int vfd, afd;
+ int vfd, afd, c;
int filefd;
- char *videodev = "/dev/dvb/adapter0/video0";
- char *audiodev = "/dev/dvb/adapter0/audio0";
+ const char *videodev = "/dev/dvb/adapter0/video0";
+ const char *audiodev = "/dev/dvb/adapter0/audio0";
+
+ if (((tcgetpgrp(STDIN_FILENO) == getpid()) || (getppid() != (pid_t)1))
+ && (tcgetattr(STDIN_FILENO, &term) == 0)) {
+ struct termios newterm;
+ memcpy(&newterm, &term, sizeof(struct termios));
+ newterm.c_iflag = 0;
+ newterm.c_lflag &= ~(ICANON | ECHO);
+ newterm.c_cc[VMIN] = 0;
+ newterm.c_cc[VTIME] = 0;
+ atexit(restore);
+ tcsetattr(STDIN_FILENO, TCSANOW, &newterm);
+ }
- if (argc < 2) {
- fprintf(stderr, "usage: test_av_play mpeg_A+V_PES_file\n");
- return 1;
+ opterr = 0;
+ while ((c = getopt(argc, argv, "+daA")) != -1) {
+ switch (c) {
+ case 'd':
+ dolby++;
+ break;
+ case 'a':
+ audio++;
+ break;
+ case 'A':
+ audio++;
+ black++;
+ break;
+ case '?':
+ fprintf(stderr, "usage: test_av_play [-d] [-a] [-A] mpeg_A+V_PES_file\n");
+ return 1;
+ default:
+ break;
+ }
}
+ argv += optind;
+ argc -= optind;
if (getenv("VIDEO"))
videodev = getenv("VIDEO");
if (getenv("AUDIO"))
- videodev = getenv("AUDIO");
+ audiodev = getenv("AUDIO");
printf("using video device '%s'\n", videodev);
printf("using audio device '%s'\n", audiodev);
- if ( (filefd = open(argv[1],O_RDONLY)) < 0){
+ putchar('\n');
+
+ printf("Freeze by pressing `z'\n");
+ printf("Stop by pressing `s'\n");
+ printf("Continue by pressing `c'\n");
+ printf("Start by pressing `p'\n");
+ printf("FastForward by pressing `f'\n");
+ printf("Mute by pressing `m'\n");
+ printf("UnMute by pressing `u'\n");
+ printf("MP2/AC3 by pressing `d'\n");
+ printf("SlowMotion by pressing `l'\n");
+ printf("Quit by pressing `q'\n");
+
+ putchar('\n');
+
+ errno = ENOENT;
+ if (!argv[0] || (filefd = open(argv[0], O_RDONLY)) < 0) {
perror("File open:");
return -1;
}
- if((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0){
+ if ((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0) {
perror("VIDEO DEVICE: ");
return -1;
}
- if((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0){
+ if ((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0) {
perror("AUDIO DEVICE: ");
return -1;
}
+
play_file_av(filefd, vfd, afd);
close(vfd);
close(afd);
close(filefd);
return 0;
-
-
}
-
diff --git a/test/test_dvr.c b/test/test_dvr.c
index 4cee62f..f61f872 100644
--- a/test/test_dvr.c
+++ b/test/test_dvr.c
@@ -82,7 +82,7 @@ static void process_data(int dvrfd, int tsfd)
fprintf(stderr, "got %d bytes (%llu total)\n", bytes, total_bytes);
}
-static int add_filter(unsigned int pid, const unsigned char* dmxdev)
+static int add_filter(unsigned int pid, const char* dmxdev)
{
int fd;
struct dmx_pes_filter_params f;
@@ -161,4 +161,3 @@ int main(int argc, char *argv[])
close(dvrfd);
return 0;
}
-
diff --git a/test/test_dvr_play.c b/test/test_dvr_play.c
index af963d9..7ab665f 100644
--- a/test/test_dvr_play.c
+++ b/test/test_dvr_play.c
@@ -141,4 +141,3 @@ int main(int argc, char **argv)
close(filefd);
return 0;
}
-
diff --git a/test/test_front.c b/test/test_front.c
index 1d08fc6..72acbb6 100644
--- a/test/test_front.c
+++ b/test/test_front.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_front.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -40,7 +40,7 @@ int OSTSelftest(int fd)
{
int ans;
- if ( (ans = ioctl(fd,OST_SELFTEST,0) < 0)){
+ if ((ans = ioctl(fd,OST_SELFTEST,0)) < 0) {
perror("OST SELF TEST: ");
return -1;
}
@@ -52,7 +52,7 @@ int OSTSetPowerState(int fd, uint32_t state)
{
int ans;
- if ( (ans = ioctl(fd,OST_SET_POWER_STATE,state) < 0)){
+ if ((ans = ioctl(fd,OST_SET_POWER_STATE,state)) < 0) {
perror("OST SET POWER STATE: ");
return -1;
}
@@ -64,7 +64,7 @@ int OSTGetPowerState(int fd, uint32_t *state)
{
int ans;
- if ( (ans = ioctl(fd,OST_GET_POWER_STATE,state) < 0)){
+ if ((ans = ioctl(fd,OST_GET_POWER_STATE,state)) < 0) {
perror("OST GET POWER STATE: ");
return -1;
}
@@ -95,7 +95,7 @@ int FEReadStatus(int fd)
int ans;
feStatus stat;
- if ( (ans = ioctl(fd,FE_READ_STATUS,&stat) < 0)){
+ if ((ans = ioctl(fd,FE_READ_STATUS,&stat)) < 0) {
perror("FE READ STATUS: ");
return -1;
}
@@ -116,7 +116,7 @@ int FEReadBER(int fd, uint32_t *ber)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_BER, ber) < 0)){
+ if ((ans = ioctl(fd,FE_READ_BER, ber)) < 0) {
perror("FE READ_BER: ");
return -1;
}
@@ -129,7 +129,7 @@ int FEReadSignalStrength(int fd, int32_t *strength)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_SIGNAL_STRENGTH, strength) < 0)){
+ if ((ans = ioctl(fd,FE_READ_SIGNAL_STRENGTH, strength)) < 0) {
perror("FE READ SIGNAL STRENGTH: ");
return -1;
}
@@ -142,7 +142,7 @@ int FEReadSNR(int fd, int32_t *snr)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_SNR, snr) < 0)){
+ if ((ans = ioctl(fd,FE_READ_SNR, snr)) < 0) {
perror("FE READ_SNR: ");
return -1;
}
@@ -156,7 +156,7 @@ int FEReadUncorrectedBlocks(int fd, uint32_t *ucb)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_UNCORRECTED_BLOCKS, ucb) < 0)){
+ if ((ans = ioctl(fd,FE_READ_UNCORRECTED_BLOCKS, ucb)) < 0) {
perror("FE READ UNCORRECTED BLOCKS: ");
return -1;
}
@@ -169,7 +169,7 @@ int FEGetNextFrequency(int fd, uint32_t *nfr)
{
int ans;
- if ( (ans = ioctl(fd,FE_GET_NEXT_FREQUENCY, nfr) < 0)){
+ if ((ans = ioctl(fd,FE_GET_NEXT_FREQUENCY, nfr)) < 0) {
perror("FE GET NEXT FREQUENCY: ");
return -1;
}
@@ -182,7 +182,7 @@ int FEGetNextSymbolRate(int fd, uint32_t *nsr)
{
int ans;
- if ( (ans = ioctl(fd,FE_GET_NEXT_SYMBOL_RATE, nsr) < 0)){
+ if ((ans = ioctl(fd,FE_GET_NEXT_SYMBOL_RATE, nsr)) < 0) {
perror("FE GET NEXT SYMBOL RATE: ");
return -1;
}
@@ -195,7 +195,7 @@ int QPSKTune(int fd, struct qpskParameters *param)
{
int ans;
- if ( (ans = ioctl(fd,QPSK_TUNE, param) < 0)){
+ if ((ans = ioctl(fd,QPSK_TUNE, param)) < 0) {
perror("QPSK TUNE: ");
return -1;
}
@@ -207,7 +207,7 @@ int QPSKGetEvent (int fd, struct qpskEvent *event)
{
int ans;
- if ( (ans = ioctl(fd,QPSK_GET_EVENT, event) < 0)){
+ if ((ans = ioctl(fd,QPSK_GET_EVENT, event)) < 0) {
perror("QPSK GET EVENT: ");
return -1;
}
@@ -219,7 +219,7 @@ int QPSKFEInfo (int fd, struct qpskFrontendInfo *info)
{
int ans;
- if ( (ans = ioctl(fd,QPSK_FE_INFO, info) < 0)){
+ if ((ans = ioctl(fd,QPSK_FE_INFO, info)) < 0) {
perror("QPSK FE INFO: ");
return -1;
}
@@ -238,7 +238,7 @@ int SecGetStatus (int fd, struct secStatus *state)
{
int ans;
- if ( (ans = ioctl(fd,SEC_GET_STATUS, state) < 0)){
+ if ((ans = ioctl(fd,SEC_GET_STATUS, state)) < 0) {
perror("QPSK GET EVENT: ");
return -1;
}
@@ -261,7 +261,7 @@ int SecGetStatus (int fd, struct secStatus *state)
break;
}
-
+
switch (state->selVolt){
case SEC_VOLTAGE_OFF:
printf("SEC VOLTAGE: OFF (%d)\n",state->selVolt);
@@ -299,11 +299,11 @@ main(int argc, char **argv)
struct qpskFrontendInfo info;
struct secStatus sec_state;
- if((fd = open("/dev/ost/qpskfe",O_RDWR)) < 0){
+ if ((fd = open("/dev/ost/qpskfe",O_RDWR)) < 0){
perror("FRONTEND DEVICE: ");
return -1;
}
- if((fd_sec = open("/dev/ost/sec",O_RDWR)) < 0){
+ if ((fd_sec = open("/dev/ost/sec",O_RDWR)) < 0){
perror("SEC DEVICE: ");
return -1;
}
@@ -325,4 +325,3 @@ main(int argc, char **argv)
close(fd);
close(fd_sec);
}
-
diff --git a/test/test_sec_ne.c b/test/test_sec_ne.c
index 9fcc8b3..350ac09 100644
--- a/test/test_sec_ne.c
+++ b/test/test_sec_ne.c
@@ -65,7 +65,7 @@ void process_section(int fd)
}
int set_filter(int fd, unsigned int pid, unsigned int tid,
- unsigned int tid_ext, unsigned int version_number)
+ unsigned int tid_ext, unsigned int _version_number)
{
struct dmx_sct_filter_params f;
unsigned long bufsz;
@@ -92,8 +92,8 @@ int set_filter(int fd, unsigned int pid, unsigned int tid,
f.filter.mask[1] = 0xff;
f.filter.mask[2] = 0xff;
}
- if (version_number < 0x20) {
- f.filter.filter[3] = (uint8_t) (version_number << 1);
+ if (_version_number < 0x20) {
+ f.filter.filter[3] = (uint8_t) (_version_number << 1);
f.filter.mask[3] = 0x3e;
f.filter.mode[3] = 0x3e;
}
@@ -162,4 +162,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_sections.c b/test/test_sections.c
index d567db0..7f32cc8 100644
--- a/test/test_sections.c
+++ b/test/test_sections.c
@@ -178,7 +178,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "0x%.2x ", mask[filter_idx]);
fprintf(stderr, "\n");
-
+
if ((dmxfd = open(dmxdev, O_RDWR)) < 0){
perror("open");
return 1;
@@ -194,4 +194,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_stc.c b/test/test_stc.c
index 89f141d..7afa817 100644
--- a/test/test_stc.c
+++ b/test/test_stc.c
@@ -71,4 +71,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_stillimage.c b/test/test_stillimage.c
index 264b2c4..358c0f1 100644
--- a/test/test_stillimage.c
+++ b/test/test_stillimage.c
@@ -6,7 +6,7 @@
*
* or more advanced using netpbm and mpeg2enc (not mpeg2encode) :
* $ cat image.jpg | jpegtopnm | pnmscale -xsize=704 -ysize=576 |\
- * ppmntsc --pal | ppmtoy4m -F 25:1 -A 4:3 |\
+ * ppmntsc --pal | ppmtoy4m -F 25:1 -A 4:3 -S 420mpeg2 |\
* mpeg2enc -f 7 -T 90 -F 3 -np -a 2 -o "image.mpg"
*
*/
@@ -21,6 +21,7 @@
#include <time.h>
#include <unistd.h>
+#include <linux/types.h>
#include <linux/dvb/video.h>
@@ -82,7 +83,7 @@ next_pic:
return -1;
}
- printf ("read: %d bytes\n", read(filefd, sp.iFrame, sp.size));
+ printf ("read: %d bytes\n", (int) read(filefd, sp.iFrame, sp.size));
close(filefd);
if ((ioctl(fd, VIDEO_STILLPICTURE, &sp) < 0)) {
@@ -99,5 +100,3 @@ next_pic:
return 0;
}
-
-
diff --git a/test/test_switch.c b/test/test_switch.c
index 7f80891..b2939ad 100644
--- a/test/test_switch.c
+++ b/test/test_switch.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_switch.c - Test program for new API
*
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
@@ -42,97 +42,97 @@ int fd_demuxv;
int fd_demuxtt;
struct dmx_sct_filter_params sctFilterParams;
-
+
struct secCommand scmd;
struct secCmdSequence scmds;
-struct dmx_pes_filter_params pesFilterParams;
-struct dmx_pes_filter_params pesFilterParamsV;
-struct dmx_pes_filter_params pesFilterParamsA;
-struct dmx_pes_filter_params pesFilterParamsTT;
+struct dmx_pes_filter_params pesFilterParams;
+struct dmx_pes_filter_params pesFilterParamsV;
+struct dmx_pes_filter_params pesFilterParamsA;
+struct dmx_pes_filter_params pesFilterParamsTT;
FrontendParameters frp;
int front_type;
-set_front(void)
+set_front(void)
{
fe_status_t stat = 0;
int i, freq;
uint32_t soff;
-
+
scmds.miniCommand = SEC_MINI_NONE;
scmds.numCommands = 1;
scmds.commands = &scmd;
-
+
soff = frp.u.qpsk.SymbolRate/16000;
if (ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds) < 0)
perror("setfront sec");
usleep(100000);
-
+
freq = frp.Frequency;
-
+
while(tune_it(&frp));
-}
+}
-set_diseqc_nb(int nr)
+set_diseqc_nb(int nr)
{
scmd.type=0;
scmd.u.diseqc.addr = 0x10;
scmd.u.diseqc.cmd = 0x38;
scmd.u.diseqc.numParams = 1;
- scmd.u.diseqc.params[0] = 0xF0 | ((nr * 4) & 0x0F) |
+ scmd.u.diseqc.params[0] = 0xF0 | ((nr * 4) & 0x0F) |
(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
}
-set_ttpid(ushort ttpid)
-{
+set_ttpid(ushort ttpid)
+{
if (ttpid==0 || ttpid==0xffff || ttpid==0x1fff) {
ioctl(fd_demuxtt, DMX_STOP, 0);
return;
}
pesFilterParamsTT.pid = ttpid;
- pesFilterParamsTT.input = DMX_IN_FRONTEND;
- pesFilterParamsTT.output = DMX_OUT_DECODER;
- pesFilterParamsTT.pes_type = DMX_PES_TELETEXT;
+ pesFilterParamsTT.input = DMX_IN_FRONTEND;
+ pesFilterParamsTT.output = DMX_OUT_DECODER;
+ pesFilterParamsTT.pes_type = DMX_PES_TELETEXT;
pesFilterParamsTT.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER,
&pesFilterParamsTT) < 0) {
printf("PID=%04x\n", ttpid);
perror("set_ttpid");
}
}
-set_vpid(ushort vpid)
-{
+set_vpid(ushort vpid)
+{
if (vpid==0 || vpid==0xffff || vpid==0x1fff) {
ioctl(fd_demuxv, DMX_STOP, 0);
return;
}
pesFilterParamsV.pid = vpid;
- pesFilterParamsV.input = DMX_IN_FRONTEND;
- pesFilterParamsV.output = DMX_OUT_DECODER;
- pesFilterParamsV.pes_type = DMX_PES_VIDEO;
+ pesFilterParamsV.input = DMX_IN_FRONTEND;
+ pesFilterParamsV.output = DMX_OUT_DECODER;
+ pesFilterParamsV.pes_type = DMX_PES_VIDEO;
pesFilterParamsV.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxv, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxv, DMX_SET_PES_FILTER,
&pesFilterParamsV) < 0)
perror("set_vpid");
}
-set_apid(ushort apid)
-{
+set_apid(ushort apid)
+{
if (apid==0 || apid==0xffff || apid==0x1fff) {
ioctl(fd_demuxa, DMX_STOP, apid);
return;
}
pesFilterParamsA.pid = apid;
- pesFilterParamsA.input = DMX_IN_FRONTEND;
- pesFilterParamsA.output = DMX_OUT_DECODER;
- pesFilterParamsA.pes_type = DMX_PES_AUDIO;
+ pesFilterParamsA.input = DMX_IN_FRONTEND;
+ pesFilterParamsA.output = DMX_OUT_DECODER;
+ pesFilterParamsA.pes_type = DMX_PES_AUDIO;
pesFilterParamsA.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
&pesFilterParamsA) < 0)
perror("set_apid");
}
@@ -156,7 +156,7 @@ int tune_it(FrontendParameters *frp)
if (poll(pfd,1,3000)){
if (pfd[0].revents & POLLIN){
printf("Getting QPSK event\n");
- if ( ioctl(fd_frontend, FE_GET_EVENT, &event)
+ if ( ioctl(fd_frontend, FE_GET_EVENT, &event)
== -EOVERFLOW){
perror("qpsk get event");
@@ -170,7 +170,7 @@ int tune_it(FrontendParameters *frp)
case FE_FAILURE_EV:
printf("failure event\n");
return -1;
-
+
case FE_COMPLETION_EV:
printf("completion event\n");
}
@@ -179,7 +179,7 @@ int tune_it(FrontendParameters *frp)
return 0;
}
-set_tp(uint *freq, int ttk, int pol, uint srate, int dis)
+set_tp(uint *freq, int ttk, int pol, uint srate, int dis)
{
if (*freq < 11700000) {
frp.Frequency = (*freq - 9750000);
@@ -195,22 +195,22 @@ set_tp(uint *freq, int ttk, int pol, uint srate, int dis)
frp.u.qpsk.FEC_inner = 0;
}
-get_front(void)
+get_front(void)
{
set_vpid(0);
set_apid(0);
set_ttpid(0);
- scmds.voltage = SEC_VOLTAGE_18;
+ scmds.voltage = SEC_VOLTAGE_18;
scmds.miniCommand = SEC_MINI_NONE;
scmds.continuousTone = SEC_TONE_OFF;
scmds.numCommands=1;
scmds.commands=&scmd;
-
+
frp.Frequency=(12073000-10600000);
frp.u.qpsk.SymbolRate=25378000;
frp.u.qpsk.FEC_inner=(fe_code_rate_t)5;
-}
-
+}
+
void get_sect(int fd)
{
@@ -219,10 +219,10 @@ void get_sect(int fd)
uint16_t cpid = 0;
uint16_t length;
struct pollfd pfd;
-
+
pfd.fd = fd;
pfd.events = POLLIN;
-
+
while (1){
if (poll(&pfd, 1, 5000) != POLLIN) {
printf("not found\n");
@@ -232,7 +232,7 @@ void get_sect(int fd)
length = (sec[1]& 0x0F)<<8;
length |= (sec[2]& 0xFF);
-
+
for (i= 0; i < length+3; i++) {
printf("0x%02x ",sec[i]);
@@ -248,7 +248,7 @@ int FEReadStatus(int fd, fe_status_t *stat)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){
+ if ((ans = ioctl(fd,FE_READ_STATUS,stat)) < 0) {
perror("FE READ STATUS: ");
return -1;
}
@@ -268,7 +268,7 @@ int FEReadStatus(int fd, fe_status_t *stat)
int has_signal()
{
fe_status_t stat;
-
+
FEReadStatus(fd_frontend, &stat);
if (stat & FE_HAS_SIGNAL)
return 1;
@@ -304,7 +304,7 @@ main()
scmds.commands=&scmd;
frp.Frequency = (12073000 - 10600000);
// frp.Frequency = (11975000 - 10600000);
- scmds.continuousTone = SEC_TONE_ON;
+ scmds.continuousTone = SEC_TONE_ON;
frp.u.qpsk.SymbolRate = 25378000;
// frp.u.qpsk.SymbolRate = 27500000;
// frp.u.qpsk.FEC_inner = FEC_AUTO;
@@ -313,7 +313,7 @@ main()
scmd.u.diseqc.addr = 0x10;
scmd.u.diseqc.cmd = 0x38;
scmd.u.diseqc.numParams = 1;
- scmd.u.diseqc.params[0] = 0xF0 | ((3 * 4) & 0x0F) |
+ scmd.u.diseqc.params[0] = 0xF0 | ((3 * 4) & 0x0F) |
(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
@@ -324,7 +324,7 @@ main()
/*
- if ((fd_demuxa=open("/dev/ost/demux", O_RDWR|O_NONBLOCK))
+ if ((fd_demuxa=open("/dev/ost/demux", O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
@@ -336,18 +336,18 @@ main()
sctFilterParams.timeout = 0;
sctFilterParams.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxa, DMX_SET_FILTER, &sctFilterParams) < 0)
+ if (ioctl(fd_demuxa, DMX_SET_FILTER, &sctFilterParams) < 0)
perror("DMX SET FILTER:");
get_sect(fd_demuxa);
*/
pesFilterParamsA.pid = 0x1fff;
- pesFilterParamsA.input = DMX_IN_FRONTEND;
- pesFilterParamsA.output = DMX_OUT_TS_TAP;
- pesFilterParamsA.pes_type = DMX_PES_OTHER;
+ pesFilterParamsA.input = DMX_IN_FRONTEND;
+ pesFilterParamsA.output = DMX_OUT_TS_TAP;
+ pesFilterParamsA.pes_type = DMX_PES_OTHER;
pesFilterParamsA.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
&pesFilterParamsA) < 0)
perror("set_apid");
diff --git a/test/test_tt.c b/test/test_tt.c
index 6511f39..da288d3 100644
--- a/test/test_tt.c
+++ b/test/test_tt.c
@@ -202,4 +202,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_vevent.c b/test/test_vevent.c
index f61143e..bfd0369 100644
--- a/test/test_vevent.c
+++ b/test/test_vevent.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_vevent.c - Test VIDEO_GET_EVENT and poll(9 for video events
*
* Copyright (C) 2003 convergence GmbH
@@ -29,6 +29,7 @@
#include <time.h>
#include <unistd.h>
+#include <linux/types.h>
#include <linux/dvb/video.h>
@@ -73,7 +74,7 @@ int main(void)
printf("using video device '%s'\n", videodev);
- if((vfd = open(videodev, O_RDONLY | O_NONBLOCK)) < 0) {
+ if ((vfd = open(videodev, O_RDONLY | O_NONBLOCK)) < 0) {
perror("open video device");
return 1;
}
@@ -122,4 +123,3 @@ int main(void)
close(vfd);
return 0;
}
-
diff --git a/test/test_video.c b/test/test_video.c
index 09c2be1..ac66050 100644
--- a/test/test_video.c
+++ b/test/test_video.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_video.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -40,7 +40,7 @@ int videoStop(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){
+ if ((ans = ioctl(fd,VIDEO_STOP,0)) < 0) {
perror("VIDEO STOP: ");
return -1;
}
@@ -52,7 +52,7 @@ int videoPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){
+ if ((ans = ioctl(fd,VIDEO_PLAY)) < 0) {
perror("VIDEO PLAY: ");
return -1;
}
@@ -65,7 +65,7 @@ int videoFreeze(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FREEZE)) < 0) {
perror("VIDEO FREEZE: ");
return -1;
}
@@ -78,7 +78,7 @@ int videoContinue(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_CONTINUE)) < 0) {
perror("VIDEO CONTINUE: ");
return -1;
}
@@ -90,7 +90,7 @@ int videoSelectSource(int fd, video_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SELECT_SOURCE, source)) < 0) {
perror("VIDEO SELECT SOURCE: ");
return -1;
}
@@ -104,7 +104,7 @@ int videoSetBlank(int fd, boolean state)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SET_BLANK, state) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SET_BLANK, state)) < 0) {
perror("VIDEO SET BLANK: ");
return -1;
}
@@ -116,7 +116,7 @@ int videoFastForward(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes)) < 0) {
perror("VIDEO FAST FORWARD: ");
return -1;
}
@@ -128,7 +128,7 @@ int videoSlowMotion(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SLOWMOTION, nframes)) < 0) {
perror("VIDEO SLOWMOTION: ");
return -1;
}
@@ -141,7 +141,7 @@ int videoGetStatus(int fd)
struct video_status stat;
int ans;
- if ( (ans = ioctl(fd,VIDEO_GET_STATUS, &stat) < 0)){
+ if ((ans = ioctl(fd,VIDEO_GET_STATUS, &stat)) < 0) {
perror("VIDEO GET STATUS: ");
return -1;
}
@@ -164,7 +164,7 @@ int videoGetStatus(int fd)
printf("unknown (%d)\n",stat.play_state);
break;
}
-
+
printf(" Stream Source : ");
switch((int)stat.stream_source){
case VIDEO_SOURCE_DEMUX:
@@ -213,7 +213,7 @@ int videoStillPicture(int fd, struct video_still_picture *sp)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_STILLPICTURE, sp) < 0)){
+ if ((ans = ioctl(fd,VIDEO_STILLPICTURE, sp)) < 0) {
perror("VIDEO STILLPICTURE: ");
return -1;
}
@@ -234,17 +234,17 @@ void play_file_video(int filefd, int fd)
pfd[0].fd = STDIN_FILENO;
pfd[0].events = POLLIN;
-
+
pfd[1].fd = fd;
pfd[1].events = POLLOUT;
-
+
videoSelectSource(fd,VIDEO_SOURCE_MEMORY);
videoPlay(fd);
-
-
+
+
count = read(filefd,buf,BUFFY);
write(fd,buf,count);
-
+
while ( (count = read(filefd,buf,BUFFY)) >= 0 ){
written = 0;
while(written < count){
@@ -267,7 +267,7 @@ void play_file_video(int filefd, int fd)
printf("playback stopped\n");
stopped = 1;
break;
-
+
case 'c':
videoContinue(fd);
printf("playback continued\n");
@@ -298,7 +298,7 @@ void play_file_video(int filefd, int fd)
break;
}
}
-
+
}
}
}
@@ -310,12 +310,12 @@ void load_iframe(int filefd, int fd)
struct video_still_picture sp;
fstat(filefd, &st);
-
+
sp.iFrame = (char *) malloc(st.st_size);
sp.size = st.st_size;
printf("I-frame size: %d\n", sp.size);
-
- if(!sp.iFrame) {
+
+ if (!sp.iFrame) {
printf("No memory for I-Frame\n");
return;
}
@@ -338,12 +338,12 @@ main(int argc, char **argv)
perror("File open:");
return -1;
}
- if((fd = open("/dev/ost/video1",O_RDWR|O_NONBLOCK)) < 0){
+ if ((fd = open("/dev/ost/video1",O_RDWR|O_NONBLOCK)) < 0){
perror("VIDEO DEVICE: ");
return -1;
}
-
-
+
+
// videoSetBlank(fd,false);
@@ -365,4 +365,3 @@ main(int argc, char **argv)
}
-
diff --git a/test/video.c b/test/video.c
index ea9e4a2..fae421e 100644
--- a/test/video.c
+++ b/test/video.c
@@ -1,13 +1,14 @@
- /**
- * A tiny video watching application, just starts capturing /dev/video
- * into /dev/fb0.
- * Be shure to have >8Bit/pixel color resolution and r/w access for
- * /dev/video0, /dev/fb0 and /dev/tty0 to let this work...
- *
- * compile with
- *
- * $ gcc -g -Wall -O2 -o video video.c -I../../ost/include
- */
+#define USAGE \
+"\n" \
+"\n A tiny video watching application, just starts capturing /dev/video" \
+"\n into /dev/fb0." \
+"\n Be shure to have >8Bit/pixel color resolution and r/w access for " \
+"\n /dev/video0, /dev/fb0 and /dev/tty0 to let this work..." \
+"\n" \
+"\n compile with" \
+"\n" \
+"\n $ gcc -g -Wall -O2 -o video video.c -I../../ost/include" \
+"\n"
#include <sys/mman.h>
#include <sys/ioctl.h>
@@ -55,7 +56,7 @@ int init_fb (void)
}
write( vt_fd, blankoff_str, strlen(blankoff_str) );
-
+
if (ioctl (fd, FBIOGET_VSCREENINFO, &fb_var) < 0) {
perror("Could not get variable screen information (fb_var)\n");
return 1;
@@ -77,14 +78,14 @@ int init_video (int stop)
struct video_capability vcap;
if ((fd = open (video_devname, O_RDWR)) < 0) {
- fprintf (stderr,
+ fprintf (stderr,
"%s: Could not open %s, please check permissions\n",
__FUNCTION__, video_devname);
return -1;
}
ioctl(fd, VIDIOCGCAP, &vcap);
-
+
if (ioctl(fd, VIDIOCCAPTURE, &zero) < 0) {
perror("Could not stop capturing (VIDIOCCAPTURE failed)\n");
return -2;
@@ -92,7 +93,7 @@ int init_video (int stop)
if (stop)
return 0;
-
+
{
struct video_buffer b;
b.base = (void*) fb_fix.smem_start;
@@ -105,7 +106,7 @@ int init_video (int stop)
return -3;
}
}
-
+
{
struct video_picture p;
if (ioctl(fd, VIDIOCGPICT, &p) < 0) {
@@ -131,7 +132,7 @@ int init_video (int stop)
return -5;
}
}
-
+
{
struct video_window win;
win.width = min((__u32) vcap.maxwidth, fb_var.xres);
@@ -147,14 +148,14 @@ int init_video (int stop)
return -6;
}
}
-
+
if (ioctl(fd, VIDIOCCAPTURE, &one) < 0) {
perror("Could not start capturing (VIDIOCCAPTURE failed)\n");
return -7;
}
-
+
close (fd);
-
+
return 0;
}
@@ -173,10 +174,9 @@ int main (int argc, char **argv)
video_devname = argv[1];
if (argc != 1 && argc != 2 && !(argc == 3 && stop)) {
- fprintf (stderr, "usage: %s <devname> <stop>\n", argv[0]);
+ fprintf(stderr, "usage: %s <devname> <stop>\n" USAGE, argv[0]);
exit (-1);
}
return init_video (stop);
}
-
diff --git a/util/Makefile b/util/Makefile
index 6e6daa3..c7a83db 100644
--- a/util/Makefile
+++ b/util/Makefile
@@ -1,12 +1,18 @@
# Makefile for linuxtv.org dvb-apps/util
-%:: FORCE
- $(MAKE) -C lib $(MAKECMDGOALS)
- $(MAKE) -C szap $(MAKECMDGOALS)
- $(MAKE) -C scan $(MAKECMDGOALS)
- $(MAKE) -C dvbnet $(MAKECMDGOALS)
- $(MAKE) -C dvbdate $(MAKECMDGOALS)
- $(MAKE) -C dvbtraffic $(MAKECMDGOALS)
- $(MAKE) -C av7110_loadkeys $(MAKECMDGOALS)
+.PHONY: all clean install
-FORCE:
+all clean install:
+ $(MAKE) -C av7110_loadkeys $@
+ $(MAKE) -C dib3000-watch $@
+ $(MAKE) -C dst-utils $@
+ $(MAKE) -C dvbdate $@
+ $(MAKE) -C dvbnet $@
+ $(MAKE) -C dvbtraffic $@
+ $(MAKE) -C dvbscan $@
+ $(MAKE) -C femon $@
+ $(MAKE) -C scan $@
+ $(MAKE) -C szap $@
+ $(MAKE) -C ttusb_dec_reset $@
+ $(MAKE) -C gnutv $@
+ $(MAKE) -C zap $@
diff --git a/util/av7110_loadkeys/Makefile b/util/av7110_loadkeys/Makefile
index e83e069..f83b529 100644
--- a/util/av7110_loadkeys/Makefile
+++ b/util/av7110_loadkeys/Makefile
@@ -1,48 +1,23 @@
-CC = gcc
-CFLAGS = -g -Wall -O2
-
-all: av7110_loadkeys evtest
-
-av7110_loadkeys: av7110_loadkeys.o
-
-evtest: evtest.o
-
-av7110_loadkeys.o: av7110_loadkeys.c input_keynames.h
-
-evtest.o: evtest.c input_keynames.h
-
-
-input_keynames.h: /usr/include/linux/input.h input_fake.h
- @echo 'generate $@...'
- @echo '#ifndef __INPUT_KEYNAMES_H__' > $@
- @echo '#define __INPUT_KEYNAMES_H__' >> $@
- @echo '' >> $@
- @echo '#include <linux/input.h>' >> $@
- @echo '' >> $@
- @echo '#if !defined(KEY_OK)' >> $@
- @echo '#include "input_fake.h"' >> $@
- @echo '#endif' >> $@
- @echo '' >> $@
- @echo '' >> $@
- @echo 'struct input_key_name {' >> $@
- @echo ' const char *name;' >> $@
- @echo ' int key;' >> $@
- @echo '};' >> $@
- @echo '' >> $@
- @echo '' >> $@
- @echo 'static struct input_key_name key_name [] = {' >> $@
- @for x in `cat /usr/include/linux/input.h input_fake.h | \
- grep KEY_ | grep "#define" | grep -v KEY_MAX | \
- cut -f 1 | cut -f 2 -d ' ' | sort | uniq` ; do \
- echo " { \"`echo $$x | cut -b 5-`\", $$x }," >> $@ \
- ; \
- done
- @echo '};' >> $@
- @echo '' >> $@
- @echo '#endif /* __INPUT_KEYNAMES_H */' >> $@
- @echo '' >> $@
-
-
-clean:
- $(RM) core* *.o input_keynames.h av7110_loadkeys evtest
+# Makefile for linuxtv.org dvb-apps/util/av7110_loadkeys
+binaries = av7110_loadkeys
+
+inst_bin = $(binaries)
+
+removing = input_keynames.h
+
+.PHONY: all
+
+all: $(binaries)
+
+$(binaries): input_keynames.h
+
+input_keynames.h:
+ $(SHELL) generate-keynames.sh $@
+
+include ../../Make.rules
+
+install::
+ @echo installing av7110 keymaps
+ @mkdir -p $(DESTDIR)$(sharedir)/dvb/av7110_loadkeys
+ @install -m 644 *.rc5 *.rcmm $(DESTDIR)$(sharedir)/dvb/av7110_loadkeys/
diff --git a/util/av7110_loadkeys/README b/util/av7110_loadkeys/README
index b778e9a..e0505dc 100644
--- a/util/av7110_loadkeys/README
+++ b/util/av7110_loadkeys/README
@@ -1,13 +1,13 @@
Hi,
-this is a utility to setup IR control keymaps using the /proc/av7110_ir
+this is a utility to setup IR control keymaps using the /proc/av7110_ir
interface.
-just call
+just call
# ./av7110_loadkeys [-i|--invert] [-a|--address <num>] keymapname.(rc5|rcmm) > /proc/av7110_ir
-If your IR receiver hardware inverts the signal, you should use the -i
+If your IR receiver hardware inverts the signal, you should use the -i
or --invert command line option.
If you have two or more devices which use the same IR protocol, you should
@@ -42,7 +42,7 @@ Keymaps are in format:
------------------------------------------------------------------------
-In order to write a new keymap you might want to see the raw key
+In order to write a new keymap you might want to see the raw key
values in the kernel log. Use
# insmod dvb-ttpci.o av7110_ir_debug=1
@@ -52,13 +52,12 @@ the kernel log while pressing your remote control keys. When you don't see
any messages in your kernel log you should check all electrical connections,
the selected protocol (RC5 or RCMM?) and the inversion setting.
-You find a list of all linux input key identifiers in </usr/include/input.h>
+You find a list of all linux input key identifiers in </usr/include/input.h>
and "./input_fake.h".
-Please post new keymaps on the linux-dvb mailing list or send them to
+Please post new keymaps on the linux-dvb mailing list or send them to
me <holger@convergence.de>.
-have fun!
+have fun!
Holger
-
diff --git a/util/av7110_loadkeys/activy.rcmm b/util/av7110_loadkeys/activy.rcmm
index 372df8e..c7d7280 100644
--- a/util/av7110_loadkeys/activy.rcmm
+++ b/util/av7110_loadkeys/activy.rcmm
@@ -51,4 +51,3 @@
0x31 KEY_STOP
0x20 KEY_NEXT
0x42 KEY_EJECTCD
-
diff --git a/util/av7110_loadkeys/av7110_loadkeys.c b/util/av7110_loadkeys/av7110_loadkeys.c
index e9eeea0..793862f 100644
--- a/util/av7110_loadkeys/av7110_loadkeys.c
+++ b/util/av7110_loadkeys/av7110_loadkeys.c
@@ -33,9 +33,10 @@ void print_error (const char *action, const char *file)
static
int parse_keyname (char *pos, char **nend, int limit)
{
- int cmp, index;
+ int cmp, _index;
int l = 1;
- int r = sizeof (key_name) / sizeof (key_name[0]);
+ const struct input_key_name *kn;
+ int r;
if (limit < 5)
return -1;
@@ -46,7 +47,18 @@ int parse_keyname (char *pos, char **nend, int limit)
limit--;
}
- if (pos [0] != 'K' || pos[1] != 'E' || pos[2] != 'Y' || pos[3] != '_')
+ if (pos[3] != '_')
+ return -2;
+
+ if (pos[0] == 'K' && pos[1] == 'E' && pos[2] == 'Y') {
+ kn = key_name;
+ r = sizeof (key_name) / sizeof (key_name[0]);
+ }
+ else if (pos[0] == 'B' && pos[1] == 'T' && pos[2] == 'N') {
+ kn = btn_name;
+ r = sizeof (btn_name) / sizeof (btn_name[0]);
+ }
+ else
return -2;
(*nend) += 4;
@@ -56,21 +68,21 @@ int parse_keyname (char *pos, char **nend, int limit)
while (r >= l) {
int len0, len1 = 0;
- index = (l + r) / 2;
-
- len0 = strlen(key_name[index-1].name);
+ _index = (l + r) / 2;
+
+ len0 = strlen(kn[_index-1].name);
while (len1 < limit && isgraph(pos[len1]))
len1++;
- cmp = strncmp (key_name[index-1].name, pos,
- strlen(key_name[index-1].name));
-
+ cmp = strncmp (kn[_index-1].name, pos,
+ strlen(kn[_index-1].name));
+
if (len0 < len1 && cmp == 0)
cmp = -1;
if (cmp == 0) {
- *nend = pos + strlen (key_name[index-1].name);
+ *nend = pos + strlen (kn[_index-1].name);
if (**nend != '\n' &&
**nend != '\t' &&
@@ -78,13 +90,13 @@ int parse_keyname (char *pos, char **nend, int limit)
*nend != pos)
return -3;
- return key_name[index-1].key;
+ return kn[_index-1].key;
}
if (cmp < 0)
- l = index + 1;
+ l = _index + 1;
else
- r = index - 1;
+ r = _index - 1;
if (r < l) {
static const char msg [] = "\nunknown key '";
@@ -151,18 +163,18 @@ int main (int argc, char **argv)
while (pos < buf + len) {
int key, keycode;
-
+
while (!isxdigit(*pos) && pos < buf + len)
pos++;
if (pos == buf + len)
break;
-
+
key = strtol (pos, &pos, 0);
keycode = parse_keyname (pos, &pos, buf + len - pos);
if (key < 0 || key > 0xff) {
- const char msg [] =
+ const char msg [] =
"\nERROR: key must be in range 0 ... 0xff!\n\n";
write (0, msg, strlen(msg));
@@ -174,7 +186,7 @@ int main (int argc, char **argv)
setup.keytab[key] = keycode;
}
-
+
munmap (buf, len);
close (fd);
@@ -182,5 +194,3 @@ int main (int argc, char **argv)
return 0;
}
-
-
diff --git a/util/av7110_loadkeys/evtest.c b/util/av7110_loadkeys/evtest.c
deleted file mode 100644
index 6714128..0000000
--- a/util/av7110_loadkeys/evtest.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * $Id: evtest.c,v 1.1 2004/01/17 16:59:46 js Exp $
- *
- * Copyright (c) 1999-2000 Vojtech Pavlik
- *
- * Event device test program
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/input.h>
-
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-char *events[EV_MAX + 1] = { "Reset", "Key", "Relative", "Absolute", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, "LED", "Sound", NULL, "Repeat", "ForceFeedback", NULL, "ForceFeedbackStatus"};
-char *keys[KEY_MAX + 1] = { "Reserved", "Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Minus", "Equal", "Backspace",
-"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "LeftBrace", "RightBrace", "Enter", "LeftControl", "A", "S", "D", "F", "G",
-"H", "J", "K", "L", "Semicolon", "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z", "X", "C", "V", "B", "N", "M", "Comma", "Dot",
-"Slash", "RightShift", "KPAsterisk", "LeftAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
-"NumLock", "ScrollLock", "KP7", "KP8", "KP9", "KPMinus", "KP4", "KP5", "KP6", "KPPlus", "KP1", "KP2", "KP3", "KP0", "KPDot", "103rd",
-"F13", "102nd", "F11", "F12", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "KPEnter", "RightCtrl", "KPSlash", "SysRq",
-"RightAlt", "LineFeed", "Home", "Up", "PageUp", "Left", "Right", "End", "Down", "PageDown", "Insert", "Delete", "Macro", "Mute",
-"VolumeDown", "VolumeUp", "Power", "KPEqual", "KPPlusMinus", "Pause", "F21", "F22", "F23", "F24", "KPComma", "LeftMeta", "RightMeta",
-"Compose", "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open", "Paste", "Find", "Cut", "Help", "Menu", "Calc", "Setup",
-"Sleep", "WakeUp", "File", "SendFile", "DeleteFile", "X-fer", "Prog1", "Prog2", "WWW", "MSDOS", "Coffee", "Direction",
-"CycleWindows", "Mail", "Bookmarks", "Computer", "Back", "Forward", "CloseCD", "EjectCD", "EjectCloseCD", "NextSong", "PlayPause",
-"PreviousSong", "StopCD", "Record", "Rewind", "Phone", "ISOKey", "Config", "HomePage", "Refresh", "Exit", "Move", "Edit", "ScrollUp",
-"ScrollDown", "KPLeftParenthesis", "KPRightParenthesis",
-"International1", "International2", "International3", "International4", "International5",
-"International6", "International7", "International8", "International9",
-"Language1", "Language2", "Language3", "Language4", "Language5", "Language6", "Language7", "Language8", "Language9",
-NULL,
-"PlayCD", "PauseCD", "Prog3", "Prog4", "Suspend", "Close",
-NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-"Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9",
-NULL, NULL, NULL, NULL, NULL, NULL,
-"LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn",
-NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-"Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn",
-"BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6",
-NULL, NULL, NULL, "BtnDead",
-"BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode",
-"BtnThumbL", "BtnThumbR", NULL,
-"ToolPen", "ToolRubber", "ToolBrush", "ToolPencil", "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens", NULL, NULL,
-"Touch", "Stylus", "Stylus2", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-"Ok", "Select", "Goto", "Clear", "Power2", "Option", "Info", "Time", "Vendor",
-"Archive", "Program", "Channel", "Favorites", "EPG", "PVR", "MHP", "Language",
-"Title", "Subtitle", "Angle", "Zoom", "Mode", "Keyboard", "Screen", "PC", "TV",
-"TV2", "VCR", "VCR2", "Sat", "Sat2", "CD", "Tape", "Radio", "Tuner", "Player",
-"Text", "DVD", "Aux", "MP3", "Audio", "Video", "Directory", "List", "Memo",
-"Calendar", "Red", "Green", "Yellow", "Blue", "ChannelUp", "ChannelDown",
-"First", "Last", "AB", "Play", "Restart", "Slow", "Shuffle", "FastForward",
-"Previous", "Next", "Digits", "Teen", "Twen", "Break" };
-
-char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };
-char *relatives[REL_MAX + 1] = { "X", "Y", "Z", NULL, NULL, NULL, "HWheel", "Dial", "Wheel" };
-char *absolutes[ABS_MAX + 1] = { "X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder", "Wheel", "Gas", "Brake",
-NULL, NULL, NULL, NULL, NULL,
-"Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat 3Y", "Pressure", "Distance", "XTilt", "YTilt"};
-char *leds[LED_MAX + 1] = { "NumLock", "CapsLock", "ScrollLock", "Compose", "Kana", "Sleep", "Suspend", "Mute" };
-char *repeats[REP_MAX + 1] = { "Delay", "Period" };
-char *sounds[SND_MAX + 1] = { "Bell", "Click" };
-
-char **names[EV_MAX + 1] = { events, keys, relatives, absolutes, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-NULL, NULL, leds, sounds, NULL, repeats, NULL, NULL, NULL };
-
-#define BITS_PER_LONG (sizeof(long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define OFF(x) ((x)%BITS_PER_LONG)
-#define BIT(x) (1UL<<OFF(x))
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
-
-int main (int argc, char **argv)
-{
- int fd, rd, i, j, k;
- struct input_event ev[64];
- int version;
- unsigned short id[4];
- unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
- char name[256] = "Unknown";
- int abs[5];
-
- if (argc < 2) {
- printf("Usage: evtest /dev/input/eventX\n");
- printf("Where X = input device number\n");
- exit(1);
- }
-
- if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
- perror("evtest");
- exit(1);
- }
-
- if (ioctl(fd, EVIOCGVERSION, &version)) {
- perror("evtest: can't get version");
- exit(1);
- }
-
- printf("Input driver version is %d.%d.%d\n",
- version >> 16, (version >> 8) & 0xff, version & 0xff);
-
- ioctl(fd, EVIOCGID, id);
- printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
- id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
-
- ioctl(fd, EVIOCGNAME(sizeof(name)), name);
- printf("Input device name: \"%s\"\n", name);
-
- memset(bit, 0, sizeof(bit));
- ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
- printf("Supported events:\n");
-
- for (i = 0; i < EV_MAX; i++)
- if (test_bit(i, bit[0])) {
- printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
- ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
- for (j = 0; j < KEY_MAX; j++)
- if (test_bit(j, bit[i])) {
- printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
- if (i == EV_ABS) {
- ioctl(fd, EVIOCGABS(j), abs);
- for (k = 0; k < 5; k++)
- if ((k < 3) || abs[k])
- printf(" %s %6d\n", absval[k], abs[k]);
- }
- }
- }
-
-
- printf("Testing ... (interrupt to exit)\n");
-
- while (1) {
- rd = read(fd, ev, sizeof(struct input_event) * 64);
-
- if (rd < (int) sizeof(struct input_event)) {
- printf("yyy\n");
- perror("\nevtest: error reading");
- exit (1);
- }
-
- for (i = 0; i < rd / sizeof(struct input_event); i++)
- printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
- ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
- events[ev[i].type] ? events[ev[i].type] : "?",
- ev[i].code,
- names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
- ev[i].value);
-
- }
-}
-
diff --git a/util/av7110_loadkeys/galaxis.rcmm b/util/av7110_loadkeys/galaxis.rcmm
index 86268e9..38eb389 100644
--- a/util/av7110_loadkeys/galaxis.rcmm
+++ b/util/av7110_loadkeys/galaxis.rcmm
@@ -37,7 +37,7 @@
0x6e KEY_GREEN
0x6f KEY_YELLOW
0x70 KEY_BLUE
-
+
0x78 KEY_MENU
0x79 KEY_LIST
0xcc KEY_EPG
@@ -48,4 +48,3 @@
0xc7 KEY_DOWN
0xff KEY_VCR
-
diff --git a/util/av7110_loadkeys/generate-keynames.sh b/util/av7110_loadkeys/generate-keynames.sh
new file mode 100644
index 0000000..49d2b71
--- /dev/null
+++ b/util/av7110_loadkeys/generate-keynames.sh
@@ -0,0 +1,37 @@
+# Makefile helper for linuxtv.org dvb-apps/util/av7110_loadkeys
+
+echo "generate $1..."
+echo "#ifndef INPUT_KEYNAMES_H" > $1
+echo "#define INPUT_KEYNAMES_H" >> $1
+echo >> $1
+echo "#include <linux/input.h>" >> $1
+echo >> $1
+echo "#if !defined(KEY_OK)" >> $1
+echo "#include \"input_fake.h\"" >> $1
+echo "#endif" >> $1
+echo >> $1
+echo >> $1
+echo "struct input_key_name {" >> $1
+echo " const char *name;" >> $1
+echo " int key;" >> $1
+echo "};" >> $1
+echo >> $1
+echo >> $1
+echo "static struct input_key_name key_name [] = {" >> $1
+for x in $(cat /usr/include/linux/input.h input_fake.h | \
+ egrep "#define[ \t]+KEY_" | grep -v KEY_MAX | \
+ cut -f 1 | cut -f 2 -d " " | sort -u) ; do
+ echo " { \"$(echo $x | cut -b 5-)\", $x }," >> $1
+done
+echo "};" >> $1
+echo >> $1
+echo "static struct input_key_name btn_name [] = {" >> $1
+for x in $(cat /usr/include/linux/input.h input_fake.h | \
+ egrep "#define[ \t]+BTN_" | \
+ cut -f 1 | cut -f 2 -d " " | sort -u) ; do
+ echo " { \"$(echo $x | cut -b 5-)\", $x }," >> $1
+done
+echo "};" >> $1
+echo >> $1
+echo "#endif /* INPUT_KEYNAMES_H */" >> $1
+echo >> $1
diff --git a/util/av7110_loadkeys/hauppauge.rc5 b/util/av7110_loadkeys/hauppauge.rc5
index c9a65b3..f52eb85 100644
--- a/util/av7110_loadkeys/hauppauge.rc5
+++ b/util/av7110_loadkeys/hauppauge.rc5
@@ -22,4 +22,3 @@
0x22 KEY_SELECT
0x26 KEY_CYCLEWINDOWS
0x2e KEY_SCREEN
-
diff --git a/util/av7110_loadkeys/hauppauge2.rc5 b/util/av7110_loadkeys/hauppauge2.rc5
new file mode 100644
index 0000000..663fea8
--- /dev/null
+++ b/util/av7110_loadkeys/hauppauge2.rc5
@@ -0,0 +1,40 @@
+0x00 KEY_0
+0x01 KEY_1
+0x02 KEY_2
+0x03 KEY_3
+0x04 KEY_4
+0x05 KEY_5
+0x06 KEY_6
+0x07 KEY_7
+0x08 KEY_8
+0x09 KEY_9
+
+0x10 KEY_VOLUMEUP
+0x11 KEY_VOLUMEDOWN
+0x1e KEY_VENDOR
+
+0x20 KEY_CHANNELUP
+0x21 KEY_CHANNELDOWN
+0x22 KEY_SELECT
+0x26 KEY_CYCLEWINDOWS
+
+0x3d KEY_POWER
+0x3b KEY_GOTO
+0x1f KEY_BACK
+0x0d KEY_MENU
+0x0b KEY_RED
+0x2e KEY_GREEN
+0x38 KEY_YELLOW
+0x25 KEY_OK
+0x29 KEY_BLUE
+0x0f KEY_MUTE
+0x0c KEY_AUX
+0x3c KEY_SCREEN
+0x32 KEY_REWIND
+0x35 KEY_PLAY
+0x34 KEY_FORWARD
+0x37 KEY_RECORD
+0x36 KEY_STOP
+0x30 KEY_PAUSE
+0x24 KEY_LEFT
+0x1e KEY_RIGHT
diff --git a/util/av7110_loadkeys/hauppauge_grey.rc5 b/util/av7110_loadkeys/hauppauge_grey.rc5
index ac186dc..2bca524 100644
--- a/util/av7110_loadkeys/hauppauge_grey.rc5
+++ b/util/av7110_loadkeys/hauppauge_grey.rc5
@@ -1,4 +1,3 @@
-
0x3d KEY_POWER
0x3b KEY_GOTO
diff --git a/util/av7110_loadkeys/input_fake.h b/util/av7110_loadkeys/input_fake.h
index 7aecc9f..0ec96df 100644
--- a/util/av7110_loadkeys/input_fake.h
+++ b/util/av7110_loadkeys/input_fake.h
@@ -7,7 +7,7 @@
#if !defined(KEY_OK)
/**
- * define some additional remote control keys in case they
+ * define some additional remote control keys in case they
* were not already defined above in <linux/input.h>
*/
@@ -66,19 +66,16 @@
#define KEY_FIRST 0x194
#define KEY_LAST 0x195
#define KEY_AB 0x196
-#define KEY_PLAY 0x197
+#define KEY_NEXT 0x197
#define KEY_RESTART 0x198
#define KEY_SLOW 0x199
#define KEY_SHUFFLE 0x19a
-#define KEY_FASTFORWARD 0x19b
+#define KEY_BREAK 0x19b
#define KEY_PREVIOUS 0x19c
-#define KEY_NEXT 0x19d
-#define KEY_DIGITS 0x19e
-#define KEY_TEEN 0x19f
-#define KEY_TWEN 0x1a0
-#define KEY_BREAK 0x1a1
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
#endif /* !defined(KEY_OK) */
#endif /* _INPUT_FAKE_H */
-
diff --git a/util/av7110_loadkeys/philips1358.rc5 b/util/av7110_loadkeys/philips1358.rc5
index e30efba..805755e 100644
--- a/util/av7110_loadkeys/philips1358.rc5
+++ b/util/av7110_loadkeys/philips1358.rc5
@@ -26,12 +26,12 @@
0x2B KEY_PAUSE
0x2C KEY_REWIND
0x2D KEY_F4
-0x2E KEY_F3
+0x2E KEY_F3
0x32 KEY_YELLOW
0x34 KEY_BLUE
0x36 KEY_GREEN
0x37 KEY_RED
0x38 KEY_AUX
-0x3C KEY_F2
+0x3C KEY_F2
0x3D KEY_SCREEN
-0x3F KEY_F1 \ No newline at end of file
+0x3F KEY_F1
diff --git a/util/dib3000-watch/Makefile b/util/dib3000-watch/Makefile
new file mode 100644
index 0000000..2961905
--- /dev/null
+++ b/util/dib3000-watch/Makefile
@@ -0,0 +1,13 @@
+# Makefile for linuxtv.org dvb-apps/util/dib3000-watch
+
+binaries = dib3000-watch
+
+inst_bin = $(binaries)
+
+LDLIBS += -lm
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/util/dib3000-watch/README.dib3000-watch b/util/dib3000-watch/README.dib3000-watch
new file mode 100644
index 0000000..a9499d5
--- /dev/null
+++ b/util/dib3000-watch/README.dib3000-watch
@@ -0,0 +1,29 @@
+This is a small tool for gathering and evaluating more reception-related data
+from the dib3000-demodulators, than the DVB-API currently makes use of.
+
+It uses the i2c-dev-interface. In order to use it, you have to enable i2c-dev
+in your kernel. The module i2c-dev is loaded automatically, when you want to
+access the /dev/i2c-*-node.
+
+If your distribution hasn't create the /dev/i2c-*-nodes you can use the
+make-i2c-dev-script located its source directory.
+
+It is not yet completed, but works fine for all dib3000mb-demods (all of the
+USB1.1 dibusb-devices are equipped with it).
+Having a CSV output would certainly be useful, when you want to make range
+tests by driving around with your car and check the signal. Nevertheless,
+this isn't written yet, but should be easy-going. Each line then should
+have an timestamp.
+
+I cannot guarantee for the values this program calculates, I'm not a signal
+expert, thus I don't know if they are correct.
+
+Thanks to Amaury Demol from DiBcom, who provides source for showing me how to
+calculate frequencies from the demod values.
+
+Patrick Boettcher <patrick.boettcher@desy.de>
+
+PS: Please feel free to modify the source to fullfil your wishes. But please
+remember, it is released under the GPL, thus please send back patches to the
+author or to the linux-dvb mailing list, so other users can have benefit from
+it.
diff --git a/util/dib3000-watch/dib-i2c.h b/util/dib3000-watch/dib-i2c.h
new file mode 100644
index 0000000..2e9c661
--- /dev/null
+++ b/util/dib3000-watch/dib-i2c.h
@@ -0,0 +1,43 @@
+/*
+ * adapted from different kernel headers
+ * "this is the current way of doing things."-Greg K-H
+ *
+ * everything copied from linux kernel 2.6.10 source
+ */
+
+#ifndef _DIB_I2C_H
+#define _DIB_I2C_H
+
+
+/* from <linux/i2c.h> */
+#define I2C_SLAVE 0x0703
+#define I2C_SLAVE_FORCE 0x0706
+#define I2C_TENBIT 0x0704
+#define I2C_PEC 0x0708
+#define I2C_RETRIES 0x0701
+#define I2C_TIMEOUT 0x0702
+
+#define I2C_FUNCS 0x0705
+#define I2C_RDWR 0x0707
+#define I2C_SMBUS 0x0720
+
+struct i2c_msg {
+ __u16 addr;
+ __u16 flags;
+#define I2C_M_RD 0x0001
+#define I2C_M_TEN 0x0010
+#define I2C_M_NOSTART 0x4000
+#define I2C_M_REV_DIR_ADDR 0x2000
+#define I2C_M_IGNORE_NAK 0x1000
+#define I2C_M_NO_RD_ACK 0x0800
+ __u16 len;
+ __u8 *buf;
+};
+
+/* from <linux/i2c-dev.h> */
+struct i2c_rdwr_ioctl_data {
+ struct i2c_msg *msgs;
+ __u32 nmsgs;
+};
+
+#endif
diff --git a/util/dib3000-watch/dib3000-watch.c b/util/dib3000-watch/dib3000-watch.c
new file mode 100644
index 0000000..16bccb7
--- /dev/null
+++ b/util/dib3000-watch/dib3000-watch.c
@@ -0,0 +1,296 @@
+/*
+ * Tool for watching the dib3000*-demodulators,
+ * with an extended output.
+ *
+ * Copyright (C) 2005 by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <getopt.h>
+
+#include <signal.h>
+
+#include <math.h>
+
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <linux/types.h>
+
+#include "dib-i2c.h"
+#include "dib3000-watch.h"
+#include "dib3000.h"
+
+void usage (void)
+{
+ verb("usage: dib3000-watch -d <i2c-device> -a <i2c-address> [-o <type>] [-i <seconds>]\n"
+ " -d normally one of /dev/i2c-[0-255]\n"
+ " -a is 8 for DiB3000M-B and 9, 10, 11 or 12 for DiB3000M-C or DiB3000-P\n"
+ " -o output type (print|csv) (default: print)\n"
+ " -i query interval in seconds (default: 0.1)\n"
+ "\n"
+ "Don't forget to run tzap or any other dvb-tune program (vdr, kaxtv) in order to tune a channel,\n"
+ "tuning isn't done by this tool.\n"
+ "\n"
+ "A lot of thing have been taken for the dibusb, dib3000m[bc] driver from kernel and\n"
+ "from t_demod-test software created by DiBcom. Both is GPL, so is dib-demod-watch.\n"
+ "\n"
+ "Copyright (C) 2005 by Patrick Boettcher <patrick.boettcher@desy.de>\n"
+ "\n"
+ "The source of this tool is released under the GPL.\n"
+ );
+ exit(1);
+}
+
+__u16 dib_read_reg(struct dib_demod *dib,__u16 reg)
+{
+ int ret;
+ __u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
+ __u8 rb[2];
+ struct i2c_msg msg[] = {
+ { .addr = dib->i2c_addr, .flags = 0, .buf = wb, .len = 2 },
+ { .addr = dib->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+ };
+ struct i2c_rdwr_ioctl_data i2c_data = {
+ .msgs = msg,
+ .nmsgs = 2,
+ };
+
+ if ((ret = ioctl(dib->fd,I2C_RDWR,&i2c_data)) != 2) {
+ err("i2c_rdwr read failed. (%d)\n",ret);
+ return 0;
+ }
+ return (rb[0] << 8)| rb[1];
+};
+
+int dib_write_reg(struct dib_demod *dib, __u16 reg, __u16 val)
+{
+ int ret;
+ __u8 b[] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg[] = {
+ { .addr = dib->i2c_addr, .flags = 0, .buf = b, .len = 4 }
+ };
+ struct i2c_rdwr_ioctl_data i2c_data = {
+ .msgs = msg,
+ .nmsgs = 1,
+ };
+
+ if ((ret = ioctl(dib->fd,I2C_RDWR,&i2c_data)) != 1) {
+ err("i2c_rdwr write failed. (%d)\n",ret);
+ return -1;
+ }
+ return 0;
+}
+
+int dib3000mb_monitoring(struct dib_demod *dib,struct dib3000mb_monitoring *m)
+{
+ int dds_freq, p_dds_freq,
+ n_agc_power = dib_read_reg(dib,DIB3000MB_REG_AGC_POWER),
+ rf_power = dib_read_reg(dib,DIB3000MB_REG_RF_POWER),
+ timing_offset;
+ double ad_power_dB, minor_power;
+
+ m->invspec = dib_read_reg(dib,DIB3000MB_REG_DDS_INV);
+ m->nfft = dib_read_reg(dib,DIB3000MB_REG_TPS_FFT);
+
+ m->agc_lock = dib_read_reg(dib,DIB3000MB_REG_AGC_LOCK);
+ m->carrier_lock = dib_read_reg(dib,DIB3000MB_REG_CARRIER_LOCK);
+ m->tps_lock = dib_read_reg(dib,DIB3000MB_REG_TPS_LOCK);
+ m->vit_lock = dib_read_reg(dib,DIB3000MB_REG_VIT_LCK);
+ m->ts_sync_lock = dib_read_reg(dib,DIB3000MB_REG_TS_SYNC_LOCK);
+ m->ts_data_lock = dib_read_reg(dib,DIB3000MB_REG_TS_RS_LOCK);
+
+ p_dds_freq = ((dib_read_reg(dib,DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 8) |
+ ((dib_read_reg(dib,DIB3000MB_REG_DDS_FREQ_LSB) & 0xff00) >> 8);
+ dds_freq = ((dib_read_reg(dib,DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 8) |
+ ((dib_read_reg(dib,DIB3000MB_REG_DDS_VALUE_LSB) & 0xff00) >> 8);
+ if (m->invspec)
+ dds_freq = (1 << 16) - dds_freq;
+ m->carrier_offset = (double)(dds_freq - p_dds_freq) / (double)(1 << 16) * DEF_SampFreq_KHz;
+
+ m->ber = (double)((dib_read_reg(dib,DIB3000MB_REG_BER_MSB) << 16) | dib_read_reg(dib,DIB3000MB_REG_BER_LSB)) / (double) 1e8;
+ m->per = dib_read_reg(dib,DIB3000MB_REG_PACKET_ERROR_RATE);
+ m->unc = dib_read_reg(dib,DIB3000MB_REG_UNC);
+ m->fft_pos = dib_read_reg(dib,DIB3000MB_REG_FFT_WINDOW_POS);
+ m->snr = 10.0 * log10( (double)(dib_read_reg(dib,DIB3000MB_REG_SIGNAL_POWER) << 8) /
+ (double)((dib_read_reg(dib,DIB3000MB_REG_NOISE_POWER_MSB) << 16) + dib_read_reg(dib,DIB3000MB_REG_NOISE_POWER_LSB)));
+
+ m->mer = (double) ((dib_read_reg(dib,DIB3000MB_REG_MER_MSB) << 16) + dib_read_reg(dib,DIB3000MB_REG_MER_LSB))
+ / (double) (1<<9) / (m->nfft ? 767.0 : 191.0);
+
+ if (n_agc_power == 0)
+ n_agc_power = 1;
+ ad_power_dB = 10 * log10( (double)(n_agc_power) / (double)(1<<16));
+ minor_power = ad_power_dB - DEF_agc_ref_dB ;
+ m->rf_power = -DEF_gain_slope_dB * (double)rf_power/(double)(1<<16) + DEF_gain_delta_dB + minor_power;
+
+ timing_offset =
+ (dib_read_reg(dib,DIB3000MB_REG_TIMING_OFFSET_MSB) << 16) + dib_read_reg(dib,DIB3000MB_REG_TIMING_OFFSET_LSB);
+ if (timing_offset >= 0x800000)
+ timing_offset |= 0xff000000;
+ m->timing_offset_ppm = -(double)timing_offset / (double)(m->nfft ? 8192 : 2048) * 1e6 / (double)(1<<20);
+
+ return 0;
+}
+
+int dib3000mb_print_monitoring(struct dib3000mb_monitoring *m)
+{
+ printf("DiB3000M-B status\n\n");
+ printf(" AGC lock: %10d\n",m->agc_lock);
+ printf(" carrier lock: %10d\n",m->carrier_lock);
+ printf(" TPS synchronize lock: %10d\n",m->tps_lock);
+ printf(" Viterbi lock: %10d\n",m->vit_lock);
+ printf(" MPEG TS synchronize lock: %10d\n",m->ts_sync_lock);
+ printf(" MPEG TS data lock: %10d\n",m->ts_data_lock);
+ printf("\n\n");
+ printf(" spectrum inversion: %10d\n",m->invspec);
+ printf(" carrier offset: %3.7g\n",m->carrier_offset);
+ printf("\n\n");
+ printf(" bit error rate: %3.7g\n",m->ber);
+ printf(" packet error rate: %10d\n",m->per);
+ printf(" packet error count: %10d\n",m->unc);
+ printf("\n\n");
+ printf(" fft position: %10d\n",m->fft_pos);
+ printf(" transmission mode: %10s\n",m->nfft ? "8k" : "2k");
+ printf("\n\n");
+ printf(" C / (N + I) = %3.7g\n",m->snr);
+ printf(" MER = %3.7g dB\n",m->mer);
+ printf(" RF power = %3.7g dBm\n",m->rf_power);
+ printf(" timing offset = %3.7g ppm\n",m->timing_offset_ppm);
+ return 0;
+}
+
+int interrupted;
+
+void sighandler (int sig)
+{
+ (void)sig;
+ interrupted = 1;
+}
+
+typedef enum {
+ OUT_PRINT = 0,
+ OUT_CSV,
+} dib3000m_output_t;
+
+int main (int argc, char * const argv[])
+{
+ struct dib_demod dib;
+ struct dib3000mb_monitoring mon;
+ const char *dev = NULL;
+ float intervall = 0.1;
+ dib3000m_output_t out = OUT_PRINT;
+ int c;
+
+ while ((c = getopt(argc,argv,"d:a:o:i:")) != -1) {
+ switch (c) {
+ case 'd':
+ dev = optarg;
+ break;
+ case 'a':
+ dib.i2c_addr = atoi(optarg); /* The I2C address */
+ break;
+ case 'o':
+ if (strcasecmp(optarg,"print") == 0) out = OUT_PRINT;
+ else if (strcasecmp(optarg,"csv") == 0) out = OUT_CSV;
+ else usage();
+ break;
+ case 'i':
+ intervall = atof(optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (dev == NULL)
+ usage();
+
+ interrupted = 0;
+ signal(SIGINT, sighandler);
+ signal(SIGKILL, sighandler);
+ signal(SIGHUP, sighandler);
+
+ verb("will use '%s' as i2c-device and %d as i2c address.\n",dev,dib.i2c_addr);
+
+ if ((dib.fd = open(dev,O_RDWR)) < 0) {
+ err("could not open %s\n",dev);
+ exit(1);
+ }
+
+ if (ioctl(dib.fd,I2C_SLAVE,dib.i2c_addr) < 0) {
+ err("could not set i2c address\n");
+ exit(1);
+ }
+
+ if (dib_read_reg(&dib,DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) {
+ err("could not find a dib3000 demodulator at i2c-address %d\n",dib.i2c_addr);
+ exit(1);
+ }
+
+ switch (dib_read_reg(&dib,DIB3000_REG_DEVICE_ID)) {
+ case DIB3000MB_DEVICE_ID:
+ verb("found a DiB3000M-B demodulator.\n");
+ dib.rev = DIB3000MB;
+ break;
+ case DIB3000MC_DEVICE_ID:
+ verb("found a DiB3000M-C demodulator.\n");
+ dib.rev = DIB3000MC;
+ break;
+ case DIB3000P_DEVICE_ID:
+ verb("found a DiB3000-P demodulator.\n");
+ dib.rev = DIB3000P;
+ break;
+ default:
+ err("unsupported demodulator found.\n");
+ }
+
+ while (!interrupted) {
+ switch (dib.rev) {
+ case DIB3000MB:
+ dib3000mb_monitoring(&dib,&mon);
+ if (out == OUT_PRINT) {
+ printf("\E[H\E[2J");
+ dib3000mb_print_monitoring(&mon);
+ } else if (out == OUT_CSV) {
+ printf("no csv output implemented yet.\n");
+ }
+ break;
+ default:
+ interrupted=1;
+ err("no monitoring writting for this demod, yet.\n");
+ }
+ usleep((int) (intervall * 1000000));
+ }
+
+ close(dib.fd);
+
+ return 0;
+}
diff --git a/util/dib3000-watch/dib3000-watch.h b/util/dib3000-watch/dib3000-watch.h
new file mode 100644
index 0000000..6d50521
--- /dev/null
+++ b/util/dib3000-watch/dib3000-watch.h
@@ -0,0 +1,46 @@
+#ifndef __DIB_DEMOD_WATCH__
+#define __DIB_DEMOD_WATCH__
+
+#define err(args...) fprintf(stderr,"error '%s': ",strerror(errno)); fprintf(stderr,args)
+#define verb(args...) fprintf(stderr,args)
+
+typedef enum {
+ DIB3000MB = 0,
+ DIB3000MC,
+ DIB3000P,
+} dib_demod_t;
+
+
+struct dib_demod {
+ int fd;
+ __u8 i2c_addr;
+
+ dib_demod_t rev;
+};
+
+struct dib3000mb_monitoring {
+ int agc_lock;
+ int carrier_lock;
+ int tps_lock;
+ int vit_lock;
+ int ts_sync_lock;
+ int ts_data_lock;
+
+ int invspec;
+
+ int per;
+ int unc;
+
+ int fft_pos;
+
+ int nfft;
+
+ double carrier_offset;
+ double ber;
+ double snr;
+ double mer;
+ double rf_power;
+ double timing_offset_ppm;
+};
+
+#endif
diff --git a/util/dib3000-watch/dib3000.h b/util/dib3000-watch/dib3000.h
new file mode 100644
index 0000000..7c3b8bd
--- /dev/null
+++ b/util/dib3000-watch/dib3000.h
@@ -0,0 +1,56 @@
+#ifndef __DIB3000_H__
+#define __DIB3000_H__
+
+/* most of this is taken from dib3000-common.h, dib3000mc_priv.h and dib3000mb_priv.h */
+
+#define DIB3000_REG_MANUFACTOR_ID ( 1025)
+#define DIB3000_I2C_ID_DIBCOM (0x01b3)
+
+#define DIB3000_REG_DEVICE_ID ( 1026)
+#define DIB3000MB_DEVICE_ID (0x3000)
+#define DIB3000MC_DEVICE_ID (0x3001)
+#define DIB3000P_DEVICE_ID (0x3002)
+
+/* dib3000mb_priv.h */
+
+#define DIB3000MB_REG_DDS_INV ( 5)
+#define DIB3000MB_REG_AGC_LOCK ( 324)
+#define DIB3000MB_REG_CARRIER_LOCK ( 355)
+#define DIB3000MB_REG_TPS_LOCK ( 394)
+#define DIB3000MB_REG_VIT_LCK ( 421)
+#define DIB3000MB_REG_TS_SYNC_LOCK ( 423)
+#define DIB3000MB_REG_TS_RS_LOCK ( 424)
+
+#define DIB3000MB_REG_DDS_FREQ_MSB ( 6)
+#define DIB3000MB_REG_DDS_FREQ_LSB ( 7)
+#define DIB3000MB_REG_DDS_VALUE_MSB ( 339)
+#define DIB3000MB_REG_DDS_VALUE_LSB ( 340)
+
+#define DIB3000MB_REG_BER_MSB ( 414)
+#define DIB3000MB_REG_BER_LSB ( 415)
+#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417)
+#define DIB3000MB_REG_UNC ( 420)
+
+#define DIB3000MB_REG_FFT_WINDOW_POS ( 353)
+#define DIB3000MB_REG_TPS_FFT ( 404)
+
+#define DIB3000MB_REG_NOISE_POWER_MSB ( 372)
+#define DIB3000MB_REG_NOISE_POWER_LSB ( 373)
+
+#define DIB3000MB_REG_SIGNAL_POWER ( 380)
+
+#define DIB3000MB_REG_MER_MSB ( 381)
+#define DIB3000MB_REG_MER_LSB ( 382)
+
+#define DIB3000MB_REG_AGC_POWER ( 325)
+#define DIB3000MB_REG_RF_POWER ( 328)
+
+#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341)
+#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342)
+
+#define DEF_agc_ref_dB -14
+#define DEF_gain_slope_dB 100
+#define DEF_gain_delta_dB -2
+#define DEF_SampFreq_KHz 27700
+
+#endif
diff --git a/util/dib3000-watch/make-i2c-dev b/util/dib3000-watch/make-i2c-dev
new file mode 100644
index 0000000..8f02bbd
--- /dev/null
+++ b/util/dib3000-watch/make-i2c-dev
@@ -0,0 +1,6 @@
+for i in `seq 0 10`;
+do
+ mknod /dev/i2c-$i c 89 $i
+ chown root.video /dev/i2c-$i
+ chmod 664 /dev/i2c-$i
+done
diff --git a/util/dst-utils/Makefile b/util/dst-utils/Makefile
new file mode 100644
index 0000000..f705c3f
--- /dev/null
+++ b/util/dst-utils/Makefile
@@ -0,0 +1,13 @@
+# Makefile for linuxtv.org dvb-apps/util/dst-utils
+
+binaries = dst_test
+
+inst_bin = $(binaries)
+
+CPPFLAGS += -I../../lib
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/util/dst-utils/dst_test.c b/util/dst-utils/dst_test.c
new file mode 100644
index 0000000..74385de
--- /dev/null
+++ b/util/dst-utils/dst_test.c
@@ -0,0 +1,258 @@
+/*
+ DST-TEST utility
+ an implementation for the High Level Common Interface
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/ca.h>
+#include <libdvben50221/en50221_app_tags.h>
+
+#define CA_NODE "/dev/dvb/adapter0/ca0"
+
+static int dst_comms(int cafd, uint32_t tag, uint32_t function, struct ca_msg *msg)
+{
+ if (tag) {
+ msg->msg[2] = tag & 0xff;
+ msg->msg[1] = (tag & 0xff00) >> 8;
+ msg->msg[0] = (tag & 0xff0000) >> 16;
+
+ printf("%s: Msg=[%02x %02x %02x ]\n",__FUNCTION__, msg->msg[0], msg->msg[1], msg->msg[2]);
+ }
+
+ if ((ioctl(cafd, function, msg)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int dst_get_caps(int cafd, struct ca_caps *caps)
+{
+ if ((ioctl(cafd, CA_GET_CAP, caps)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+
+ if (caps->slot_num < 1) {
+ printf ("No CI Slots found\n");
+ return -1;
+ }
+
+ printf("APP: Slots=[%d]\n", caps->slot_num);
+ printf("APP: Type=[%d]\n", caps->slot_type);
+ printf("APP: Descrambler keys=[%d]\n", caps->descr_num);
+ printf("APP: Type=[%d]\n", caps->descr_type);
+
+ return 0;
+}
+
+static int dst_get_info(int cafd, struct ca_slot_info *info)
+{
+ if ((ioctl(cafd, CA_GET_SLOT_INFO, info)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+ if (info->num < 1) {
+ printf("No CI Slots found\n");
+ return -1;
+ }
+ printf("APP: Number=[%d]\n", info->num);
+ printf("APP: Type=[%d]\n", info->type);
+ printf("APP: flags=[%d]\n", info->flags);
+
+ if (info->flags == 1)
+ printf("APP: CI High level interface\n");
+ if (info->flags == 1)
+ printf("APP: CA/CI Module Present\n");
+ else if (info->flags == 2)
+ printf("APP: CA/CI Module Ready\n");
+ else if (info->flags == 0)
+ printf("APP: No CA/CI Module\n");
+
+ return 0;
+}
+
+static int dst_reset(int cafd)
+{
+ if ((ioctl(cafd, CA_RESET)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dst_set_pid(int cafd)
+{
+ if ((ioctl(cafd, CA_SET_PID)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dst_get_descr(int cafd)
+{
+ if ((ioctl(cafd, CA_GET_DESCR_INFO)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dst_set_descr(int cafd)
+{
+ if ((ioctl(cafd, CA_SET_DESCR)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+ return 0;
+}
+
+static int dst_get_app_info(int cafd, struct ca_msg *msg)
+{
+ uint32_t tag = 0;
+
+ /* Enquire */
+ tag = TAG_CA_INFO_ENQUIRY;
+ if ((dst_comms(cafd, tag, CA_SEND_MSG, msg)) < 0) {
+ printf("%s: Dst communication failed\n", __FUNCTION__);
+ return -1;
+ }
+
+ /* Receive */
+ tag = TAG_CA_INFO;
+ if ((dst_comms(cafd, tag, CA_GET_MSG, msg)) < 0) {
+ printf("%s: Dst communication failed\n", __FUNCTION__);
+ return -1;
+ }
+
+ /* Process */
+ printf("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__);
+ printf("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n",
+ __FUNCTION__, msg->msg[7], (msg->msg[8] << 8) | msg->msg[9], (msg->msg[10] << 8) | msg->msg[11], __FUNCTION__,
+ ((char *) (&msg->msg[12])));
+ printf("%s: ==================================================================================================\n", __FUNCTION__);
+
+ return 0;
+}
+
+static int dst_session_test(int cafd, struct ca_msg *msg)
+{
+ msg->msg[0] = 0x91;
+ printf("Debugging open session request\n");
+ if ((ioctl(cafd, CA_SEND_MSG, msg)) < 0) {
+ printf("%s: ioctl failed ..\n", __FUNCTION__);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+ int cafd;
+ const char *usage = " DST-TEST: Twinhan DST and clones test utility\n"
+ " an implementation for the High Level Common Interface\n"
+ " Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)\n\n"
+ "\t dst_test options:\n"
+ "\t -c capabilities\n"
+ "\t -i info\n"
+ "\t -r reset\n"
+ "\t -p pid\n"
+ "\t -g get descr\n"
+ "\t -s set_descr\n"
+ "\t -a app_info\n"
+ "\t -t session test\n";
+
+
+ struct ca_caps *caps;
+ caps = (struct ca_caps *) malloc(sizeof (struct ca_caps));
+
+ struct ca_slot_info *info;
+ info = (struct ca_slot_info *)malloc (sizeof (struct ca_slot_info));
+
+ struct ca_msg *msg;
+ msg = (struct ca_msg *) malloc(sizeof (struct ca_msg));
+
+ if (argc < 2)
+ printf("%s\n", usage);
+
+ if (argc > 1) {
+ if ((cafd = open(CA_NODE, O_RDONLY)) < 0) {
+ printf("%s: Error opening %s\n", __FUNCTION__, CA_NODE);
+ return -1;
+ }
+
+ switch (getopt(argc, argv, "cirpgsat")) {
+ case 'c':
+ printf("%s: Capabilities\n", __FUNCTION__);
+ dst_get_caps(cafd, caps);
+ break;
+ case 'i':
+ printf("%s: Info\n", __FUNCTION__);
+ dst_get_info(cafd, info);
+ break;
+ case 'r':
+ printf("%s: Reset\n", __FUNCTION__);
+ dst_reset(cafd);
+ break;
+ case 'p':
+ printf("%s: PID\n", __FUNCTION__);
+ dst_set_pid(cafd);
+ break;
+ case 'g':
+ printf("%s: Get Desc\n", __FUNCTION__);
+ dst_get_descr(cafd);
+ break;
+ case 's':
+ printf("%s: Set Desc\n", __FUNCTION__);
+ dst_set_descr(cafd);
+ break;
+ case 'a':
+ printf("%s: App Info\n", __FUNCTION__);
+ dst_get_app_info(cafd, msg);
+ break;
+ case 't':
+ printf("%s: Session test\n", __FUNCTION__);
+ dst_session_test(cafd, msg);
+ break;
+
+ break;
+ }
+ close(cafd);
+ }
+ return 0;
+}
diff --git a/util/dvbdate/Makefile b/util/dvbdate/Makefile
index ea514db..2602512 100644
--- a/util/dvbdate/Makefile
+++ b/util/dvbdate/Makefile
@@ -1,25 +1,15 @@
+# Makefile for linuxtv.org dvb-apps/util/dvbdate
-CC = gcc
-CFLAGS = -g -O2 -MD -Wall -I. -I../../include
-LFLAGS =
+binaries = dvbdate
-OBJS = dvbdate.o
-TARGET = dvbdate
-DESTDIR = /usr/local/bin/
+inst_bin = $(binaries)
-all: $(TARGET)
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi -L../../lib/libucsi
+LDLIBS += -ldvbapi -lucsi
-.c.o:
- $(CC) $(CFLAGS) -c $< -o $@
+.PHONY: all
-$(TARGET): $(OBJS)
- $(CC) -o $@ $(OBJS) $(LFLAGS)
-
-install: all
- install -m 755 $(TARGET) $(DESTDIR)
-
-clean:
- rm -f $(TARGET) $(OBJS) core* *~ *.d
-
--include $(wildcard *.d) dummy
+all: $(binaries)
+include ../../Make.rules
diff --git a/util/dvbdate/dvbdate.c b/util/dvbdate/dvbdate.c
index 9821012..f0df437 100644
--- a/util/dvbdate/dvbdate.c
+++ b/util/dvbdate/dvbdate.c
@@ -8,7 +8,10 @@
Revamped by Johannes Stezenbach <js@convergence.de>
and Michael Hunold <hunold@convergence.de>
-
+
+ Ported to use the standard dvb libraries and add ATSC STT
+ support Andrew de Quincey <adq_dvb@lidskialf.net>
+
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
@@ -40,10 +43,10 @@
#include <errno.h>
#include <getopt.h>
#include <stdarg.h>
-
-#include <linux/dvb/dmx.h>
-
-#define bcdtoint(i) ((((i & 0xf0) >> 4) * 10) + (i & 0x0f))
+#include <libdvbapi/dvbfe.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libucsi/dvb/section.h>
+#include <libucsi/atsc/section.h>
/* How many seconds can the system clock be out before we get warned? */
#define ALLOWABLE_DELTA 30*60
@@ -54,6 +57,7 @@ int do_set;
int do_force;
int do_quiet;
int timeout = 25;
+int adapter = 0;
void errmsg(char *message, ...)
{
@@ -65,15 +69,24 @@ void errmsg(char *message, ...)
va_end(ap);
}
-void usage()
+void usage(void)
{
- fprintf(stderr, "usage: %s [-p] [-s] [-f] [-q] [-h]\n", ProgName);
+ fprintf(stderr, "usage: %s [-a] [-p] [-s] [-f] [-q] [-h]\n", ProgName);
_exit(1);
}
-void help()
+void help(void)
{
- fprintf(stderr, "\nhelp:\n" "%s [-p] [-s] [-f] [-q] [-h] [-t n]\n" " --print (print current time, TDT time and delta)\n" " --set (set the system clock to TDT time)\n" " --force (force the setting of the clock)\n" " --quiet (be silent)\n" " --help (display this message)\n"" --timout n (max seconds to wait, default: 25)\n", ProgName);
+ fprintf(stderr,
+ "\nhelp:\n"
+ "%s [-a] [-p] [-s] [-f] [-q] [-h] [-t n]\n"
+ " --adapter (adapter to use, default: 0)\n"
+ " --print (print current time, received time and delta)\n"
+ " --set (set the system clock to received time)\n"
+ " --force (force the setting of the clock)\n"
+ " --quiet (be silent)\n"
+ " --help (display this message)\n"
+ " --timeout n (max seconds to wait, default: 25)\n", ProgName);
_exit(1);
}
@@ -86,13 +99,14 @@ int do_options(int arg_count, char **arg_strings)
{"quiet", 0, 0, 'q'},
{"help", 0, 0, 'h'},
{"timeout", 1, 0, 't'},
+ {"adapter", 1, 0, 'a'},
{0, 0, 0, 0}
};
int c;
int Option_Index = 0;
while (1) {
- c = getopt_long(arg_count, arg_strings, "psfqht:", Long_Options, &Option_Index);
+ c = getopt_long(arg_count, arg_strings, "a:psfqht:", Long_Options, &Option_Index);
if (c == EOF)
break;
switch (c) {
@@ -103,6 +117,9 @@ int do_options(int arg_count, char **arg_strings)
usage();
}
break;
+ case 'a':
+ adapter = atoi(optarg);
+ break;
case 'p':
do_print = 1;
break;
@@ -134,7 +151,8 @@ int do_options(int arg_count, char **arg_strings)
case 2: /* Force */
case 3: /* Quiet */
case 4: /* Help */
- case 5: /* timout */
+ case 5: /* timeout */
+ case 6: /* adapter */
break;
default:
fprintf(stderr, "%s: unknown long option %d\n", ProgName, Option_Index);
@@ -153,125 +171,135 @@ int do_options(int arg_count, char **arg_strings)
}
/*
- * return the TDT time in UNIX time_t format
+ * Get the next UTC date packet from the TDT section
*/
-
-time_t convert_date(char *dvb_buf)
+int dvb_scan_date(time_t *rx_time, unsigned int to)
{
- int i;
- int year, month, day, hour, min, sec;
- long int mjd;
- struct tm dvb_time;
-
- mjd = (dvb_buf[0] & 0xff) << 8;
- mjd += (dvb_buf[1] & 0xff);
- hour = bcdtoint(dvb_buf[2] & 0xff);
- min = bcdtoint(dvb_buf[3] & 0xff);
- sec = bcdtoint(dvb_buf[4] & 0xff);
-/*
- * Use the routine specified in ETSI EN 300 468 V1.4.1,
- * "Specification for Service Information in Digital Video Broadcasting"
- * to convert from Modified Julian Date to Year, Month, Day.
- */
- year = (int) ((mjd - 15078.2) / 365.25);
- month = (int) ((mjd - 14956.1 - (int) (year * 365.25)) / 30.6001);
- day = mjd - 14956 - (int) (year * 365.25) - (int) (month * 30.6001);
- if (month == 14 || month == 15)
- i = 1;
- else
- i = 0;
- year += i;
- month = month - 1 - i * 12;
-
- dvb_time.tm_sec = sec;
- dvb_time.tm_min = min;
- dvb_time.tm_hour = hour;
- dvb_time.tm_mday = day;
- dvb_time.tm_mon = month - 1;
- dvb_time.tm_year = year;
- dvb_time.tm_isdst = -1;
- dvb_time.tm_wday = 0;
- dvb_time.tm_yday = 0;
- return (timegm(&dvb_time));
+ int tdt_fd;
+ uint8_t filter[18];
+ uint8_t mask[18];
+ unsigned char sibuf[4096];
+ int size;
+
+ // open the demuxer
+ if ((tdt_fd = dvbdemux_open_demux(adapter, 0, 0)) < 0) {
+ return -1;
+ }
+
+ // create a section filter for the TDT
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = stag_dvb_time_date;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(tdt_fd, TRANSPORT_TDT_PID, filter, mask, 1, 1)) {
+ close(tdt_fd);
+ return -1;
+ }
+
+ // poll for data
+ struct pollfd pollfd;
+ pollfd.fd = tdt_fd;
+ pollfd.events = POLLIN|POLLERR|POLLPRI;
+ if (poll(&pollfd, 1, to * 1000) != 1) {
+ close(tdt_fd);
+ return -1;
+ }
+
+ // read it
+ if ((size = read(tdt_fd, sibuf, sizeof(sibuf))) < 0) {
+ close(tdt_fd);
+ return -1;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ close(tdt_fd);
+ return -1;
+ }
+
+ // parse TDT
+ struct dvb_tdt_section *tdt = dvb_tdt_section_codec(section);
+ if (tdt == NULL) {
+ close(tdt_fd);
+ return -1;
+ }
+
+ // done
+ *rx_time = dvbdate_to_unixtime(tdt->utc_time);
+ close(tdt_fd);
+ return 0;
}
/*
- * Get the next UTC date packet from the TDT multiplex
+ * Get the next date packet from the STT section
*/
-
-int scan_date(time_t *dvb_time, unsigned int to)
+int atsc_scan_date(time_t *rx_time, unsigned int to)
{
- int fd_date;
- int n, seclen;
- time_t t;
- unsigned char buf[4096];
- struct dmx_sct_filter_params sctFilterParams;
- struct pollfd ufd;
- int found = 0;
-
- t = 0;
- if ((fd_date = open("/dev/dvb/adapter0/demux0", O_RDWR | O_NONBLOCK)) < 0) {
- perror("fd_date DEVICE: ");
+ int stt_fd;
+ uint8_t filter[18];
+ uint8_t mask[18];
+ unsigned char sibuf[4096];
+ int size;
+
+ // open the demuxer
+ if ((stt_fd = dvbdemux_open_demux(adapter, 0, 0)) < 0) {
return -1;
}
- memset(&sctFilterParams, 0, sizeof(sctFilterParams));
- sctFilterParams.pid = 0x14;
- sctFilterParams.timeout = 0;
- sctFilterParams.flags = DMX_IMMEDIATE_START;
- sctFilterParams.filter.filter[0] = 0x70;
- sctFilterParams.filter.mask[0] = 0xff;
+ // create a section filter for the STT
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = stag_atsc_system_time;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(stt_fd, ATSC_BASE_PID, filter, mask, 1, 1)) {
+ close(stt_fd);
+ return -1;
+ }
- if (ioctl(fd_date, DMX_SET_FILTER, &sctFilterParams) < 0) {
- perror("DATE - DMX_SET_FILTER:");
- close(fd_date);
+ // poll for data
+ struct pollfd pollfd;
+ pollfd.fd = stt_fd;
+ pollfd.events = POLLIN|POLLERR|POLLPRI;
+ if (poll(&pollfd, 1, to * 1000) != 1) {
+ close(stt_fd);
return -1;
}
- while (to > 0) {
- int res;
-
- memset(&ufd,0,sizeof(ufd));
- ufd.fd=fd_date;
- ufd.events=POLLIN;
-
- res = poll(&ufd,1,1000);
- if (0 == res) {
- fprintf(stdout, ".");
- fflush(stdout);
- to--;
- continue;
- }
- if (1 == res) {
- found = 1;
- break;
- }
- errmsg("error polling for data");
- close(fd_date);
+ // read it
+ if ((size = read(stt_fd, sibuf, sizeof(sibuf))) < 0) {
+ close(stt_fd);
+ return -1;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ close(stt_fd);
+ return -1;
+ }
+ struct section_ext *section_ext = section_ext_decode(section, 0);
+ if (section_ext == NULL) {
+ close(stt_fd);
return -1;
}
- fprintf(stdout, "\n");
- if (0 == found) {
- errmsg("timeout - try tuning to a multiplex?\n");
- close(fd_date);
+ struct atsc_section_psip *psip = atsc_section_psip_decode(section_ext);
+ if (psip == NULL) {
+ close(stt_fd);
return -1;
}
- if ((n = read(fd_date, buf, 4096)) >= 3) {
- seclen = ((buf[1] & 0x0f) << 8) | (buf[2] & 0xff);
- if (n == seclen + 3) {
- t = convert_date(&(buf[3]));
- } else {
- errmsg("Under-read bytes for DATE - wanted %d, got %d\n", seclen, n);
- return 0;
- }
- } else {
- errmsg("Nothing to read from fd_date - try tuning to a multiplex?\n");
- return 0;
+ // parse STT
+ struct atsc_stt_section *stt = atsc_stt_section_codec(psip);
+ if (stt == NULL) {
+ close(stt_fd);
+ return -1;
}
- close(fd_date);
- *dvb_time = t;
+
+ // done
+ *rx_time = atsctime_to_unixtime(stt->system_time);
+ close(stt_fd);
return 0;
}
@@ -291,10 +319,12 @@ int set_time(time_t * new_time)
int main(int argc, char **argv)
{
- time_t dvb_time;
+ time_t rx_time;
time_t real_time;
time_t offset;
int ret;
+ struct dvbfe_handle *fe;
+ struct dvbfe_info fe_info;
do_print = 0;
do_force = 0;
@@ -310,27 +340,51 @@ int main(int argc, char **argv)
errmsg("quiet and print options are mutually exclusive.\n");
exit(1);
}
+
+/*
+ * Find the frontend type
+ */
+ if ((fe = dvbfe_open(adapter, 0, 1)) == NULL) {
+ errmsg("Unable to open frontend.\n");
+ exit(1);
+ }
+ dvbfe_get_info(fe, 0, &fe_info, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
+
/*
- * Get the date from the currently tuned TDT multiplex
+ * Get the date from the currently tuned multiplex
*/
- ret = scan_date(&dvb_time, timeout);
+ switch(fe_info.type) {
+ case DVBFE_TYPE_DVBS:
+ case DVBFE_TYPE_DVBC:
+ case DVBFE_TYPE_DVBT:
+ ret = dvb_scan_date(&rx_time, timeout);
+ break;
+
+ case DVBFE_TYPE_ATSC:
+ ret = atsc_scan_date(&rx_time, timeout);
+ break;
+
+ default:
+ errmsg("Unsupported frontend type.\n");
+ exit(1);
+ }
if (ret != 0) {
errmsg("Unable to get time from multiplex.\n");
exit(1);
}
time(&real_time);
- offset = dvb_time - real_time;
+ offset = rx_time - real_time;
if (do_print) {
fprintf(stdout, "System time: %s", ctime(&real_time));
- fprintf(stdout, " TDT time: %s", ctime(&dvb_time));
+ fprintf(stdout, " RX time: %s", ctime(&rx_time));
fprintf(stdout, " Offset: %ld seconds\n", offset);
} else if (!do_quiet) {
- fprintf(stdout, "%s", ctime(&dvb_time));
+ fprintf(stdout, "%s", ctime(&rx_time));
}
if (do_set) {
if (labs(offset) > ALLOWABLE_DELTA) {
if (do_force) {
- if (0 != set_time(&dvb_time)) {
+ if (0 != set_time(&rx_time)) {
errmsg("setting the time failed\n");
}
} else {
@@ -339,7 +393,7 @@ int main(int argc, char **argv)
exit(1);
}
} else {
- set_time(&dvb_time);
+ set_time(&rx_time);
}
} /* #end if (do_set) */
return (0);
diff --git a/util/dvbnet/Makefile b/util/dvbnet/Makefile
index 187dee2..c9ebab9 100644
--- a/util/dvbnet/Makefile
+++ b/util/dvbnet/Makefile
@@ -1,29 +1,15 @@
+# Makefile for linuxtv.org dvb-apps/util/dvbnet
-CC = gcc
-CFLAGS = -g -O2 -MD -Wall -I. -I../../include
-LFLAGS =
+binaries = dvbnet
-OBJS = dvbnet.o
-TARGET = dvbnet
-DESTDIR = /usr/local/bin/
+inst_bin = $(binaries)
-all: version.h $(TARGET)
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi
+LDLIBS += -ldvbapi
-.c.o:
- $(CC) $(CFLAGS) -c $< -o $@
+.PHONY: all
-$(TARGET): $(OBJS)
- $(CC) -o $@ $(OBJS) $(LFLAGS)
-
-version.h:
- printf '#define VERSION_INFO "%s (Build %s)"\n' \
- "`cat $@.in`" "`date +'%a %b %d %X %Y'`" > $@
-
-install: all
- install -m 755 $(TARGET) $(DESTDIR)
-
-clean:
- rm -f $(TARGET) $(OBJS) version.h core* *~ *.d
-
--include $(wildcard *.d) dummy
+all: $(binaries)
+include ../../Make.rules
diff --git a/util/dvbnet/dvbnet.c b/util/dvbnet/dvbnet.c
index a58f156..53aa719 100644
--- a/util/dvbnet/dvbnet.c
+++ b/util/dvbnet/dvbnet.c
@@ -1,26 +1,29 @@
-/*
+/*
* dvbnet.c
*
* Copyright (C) 2003 TV Files S.p.A
* L.Y.Mesentsev <lymes@tiscalinet.it>
*
+ * Ported to use new DVB libraries:
+ * Copyright (C) 2006 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
+ *
*/
#include <stdio.h>
@@ -33,19 +36,10 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
-
-#include <linux/dvb/net.h>
-#include <version.h>
-
-#ifndef VERSION_INFO
-#define VERSION_INFO "1.1.1"
-#endif
+#include <libdvbapi/dvbnet.h>
#define OK 0
#define FAIL -1
-#define DVB_NET_DEVICE "/dev/dvb/adapter%d/net%d"
-#define DVB_NET_DEVICES_MAX 10
-#define IFNAME_DVB "dvb"
enum Mode {
@@ -57,14 +51,15 @@ enum Mode {
static int adapter = 0;
static int netdev = 0;
-static struct dvb_net_if net_data;
static void hello(void);
static void usage(char *);
static void parse_args(int, char **);
-static int queryInterface(int, int);
+static void queryInterface(int);
-static char dvb_net_device[40];
+int ifnum;
+int pid;
+int encapsulation;
int main(int argc, char **argv)
{
@@ -74,40 +69,36 @@ int main(int argc, char **argv)
parse_args(argc, argv);
- sprintf(dvb_net_device, DVB_NET_DEVICE, adapter, netdev);
-
- printf("Device: %s\n", dvb_net_device);
-
- if ((fd_net = open(dvb_net_device, O_RDWR | O_NONBLOCK)) < 0) {
- fprintf(stderr, "Error: couldn't open device %s: %d %m\n",
- dvb_net_device, errno);
+ if ((fd_net = dvbnet_open(adapter, netdev)) < 0) {
+ fprintf(stderr, "Error: couldn't open device %d: %d %m\n",
+ netdev, errno);
return FAIL;
}
switch (op_mode) {
case DEL_INTERFACE:
- if (ioctl(fd_net, NET_REMOVE_IF, net_data.if_num))
+ if (dvbnet_remove_interface(fd_net, ifnum))
fprintf(stderr,
"Error: couldn't remove interface %d: %d %m.\n",
- net_data.if_num, errno);
+ ifnum, errno);
else
printf("Status: device %d removed successfully.\n",
- net_data.if_num);
+ ifnum);
break;
case ADD_INTERFACE:
- if (ioctl(fd_net, NET_ADD_IF, &net_data))
+ if ((ifnum = dvbnet_add_interface(fd_net, pid, encapsulation)) < 0)
fprintf(stderr,
"Error: couldn't add interface for pid %d: %d %m.\n",
- net_data.pid, errno);
+ pid, errno);
else
printf
("Status: device dvb%d_%d for pid %d created successfully.\n",
- adapter, net_data.if_num, net_data.pid);
+ adapter, ifnum, pid);
break;
case LST_INTERFACE:
- queryInterface(fd_net, 0);
+ queryInterface(fd_net);
break;
default:
@@ -120,39 +111,48 @@ int main(int argc, char **argv)
}
-int queryInterface(int fd_net, int dev)
+void queryInterface(int fd_net)
{
- struct dvb_net_if data;
- int IF, nIFaces = 0, ret = FAIL;
+ int IF, nIFaces = 0;
+ char *encap;
printf("Query DVB network interfaces:\n");
printf("-----------------------------\n");
- for (IF = 0; IF < DVB_NET_DEVICES_MAX; IF++) {
- data.if_num = IF;
- if (ioctl(fd_net, NET_GET_IF, &data))
+ for (IF = 0; IF < DVBNET_MAX_INTERFACES; IF++) {
+ uint16_t _pid;
+ enum dvbnet_encap _encapsulation;
+ if (dvbnet_get_interface(fd_net, IF, &_pid, &_encapsulation))
continue;
- if (dev == data.if_num)
- ret = OK;
+ encap = "???";
+ switch(_encapsulation) {
+ case DVBNET_ENCAP_MPE:
+ encap = "MPE";
+ break;
+ case DVBNET_ENCAP_ULE:
+ encap = "ULE";
+ break;
+ }
printf("Found device %d: interface dvb%d_%d, "
- "listening on PID %d\n",
- IF, adapter, data.if_num, data.pid);
+ "listening on PID %d, encapsulation %s\n",
+ IF, adapter, IF, _pid, encap);
nIFaces++;
}
printf("-----------------------------\n");
printf("Found %d interface(s).\n\n", nIFaces);
- return ret;
}
void parse_args(int argc, char **argv)
{
- char c, *s;
+ int c;
+ char *s;
op_mode = UNKNOWN;
- while ((c = getopt(argc, argv, "a:n:p:d:lvh")) != EOF) {
+ encapsulation = DVBNET_ENCAP_MPE;
+ while ((c = getopt(argc, argv, "a:n:p:d:lUvh")) != EOF) {
switch (c) {
case 'a':
adapter = strtol(optarg, NULL, 0);
@@ -161,16 +161,19 @@ void parse_args(int argc, char **argv)
netdev = strtol(optarg, NULL, 0);
break;
case 'p':
- net_data.pid = strtol(optarg, NULL, 0);
+ pid = strtol(optarg, NULL, 0);
op_mode = ADD_INTERFACE;
break;
case 'd':
- net_data.if_num = strtol(optarg, NULL, 0);
+ ifnum = strtol(optarg, NULL, 0);
op_mode = DEL_INTERFACE;
break;
case 'l':
op_mode = LST_INTERFACE;
break;
+ case 'U':
+ encapsulation = DVBNET_ENCAP_ULE;
+ break;
case 'v':
exit(OK);
case 'h':
@@ -187,12 +190,12 @@ void usage(char *prog_name)
{
fprintf(stderr, "Usage: %s [options]\n", prog_name);
fprintf(stderr, "Where options are:\n");
- fprintf(stderr, "\t-a AD : Adapter card AD (default 0)\n");
- fprintf(stderr, "\t-n NET : Net demux NET (default 0)\n");
+ fprintf(stderr, "\t-a AD : Adapter card (default 0)\n");
+ fprintf(stderr, "\t-n DD : Demux (default 0)\n");
fprintf(stderr, "\t-p PID : Add interface listening on PID\n");
- fprintf(stderr, "\t-d NUM : Remove interface dvbAD_NUM\n");
- fprintf(stderr,
- "\t-l : List currently available interfaces\n");
+ fprintf(stderr, "\t-d NUM : Remove interface NUM\n");
+ fprintf(stderr, "\t-l : List currently available interfaces\n");
+ fprintf(stderr, "\t-U : use ULE framing (default: MPE)\n" );
fprintf(stderr, "\t-v : Print current version\n\n");
}
@@ -200,6 +203,5 @@ void usage(char *prog_name)
void hello(void)
{
printf("\nDVB Network Interface Manager\n");
- printf("Version %s\n", VERSION_INFO);
printf("Copyright (C) 2003, TV Files S.p.A\n\n");
}
diff --git a/util/dvbnet/net_start.pl b/util/dvbnet/net_start.pl
index 71e6367..f31ba22 100755..100644
--- a/util/dvbnet/net_start.pl
+++ b/util/dvbnet/net_start.pl
@@ -22,4 +22,3 @@ sub dvbnet
system("/sbin/ifconfig $DEV_NAME");
}
-
diff --git a/util/dvbnet/net_start.sh b/util/dvbnet/net_start.sh
index b155989..b155989 100755..100644
--- a/util/dvbnet/net_start.sh
+++ b/util/dvbnet/net_start.sh
diff --git a/util/dvbnet/version.h.in b/util/dvbnet/version.h.in
deleted file mode 100644
index d0a6e20..0000000
--- a/util/dvbnet/version.h.in
+++ /dev/null
@@ -1 +0,0 @@
-1.1.0-TVF
diff --git a/util/dvbscan/Makefile b/util/dvbscan/Makefile
new file mode 100644
index 0000000..d7e5de5
--- /dev/null
+++ b/util/dvbscan/Makefile
@@ -0,0 +1,22 @@
+# Makefile for linuxtv.org dvb-apps/util/dvbscan
+
+objects = dvbscan.o \
+ dvbscan_structutils.o \
+ dvbscan_dvb.o \
+ dvbscan_atsc.o
+
+binaries = dvbscan
+
+inst_bin = $(binaries)
+
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi -L../../lib/libdvbcfg -L../../lib/libdvbsec -L../../lib/libucsi
+LDLIBS += -ldvbcfg -lucsi -ldvbsec -ldvbapi -lpthread
+
+.PHONY: all
+
+all: $(binaries)
+
+$(binaries): $(objects)
+
+include ../../Make.rules
diff --git a/util/dvbscan/dvbscan.c b/util/dvbscan/dvbscan.c
new file mode 100644
index 0000000..c6f9ea8
--- /dev/null
+++ b/util/dvbscan/dvbscan.c
@@ -0,0 +1,370 @@
+/*
+ dvbscan utility
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <libdvbsec/dvbsec_cfg.h>
+#include <libdvbcfg/dvbcfg_scanfile.h>
+#include <libdvbapi/dvbdemux.h>
+#include "dvbscan.h"
+
+
+#define OUTPUT_TYPE_RAW 1
+#define OUTPUT_TYPE_CHANNELS 2
+#define OUTPUT_TYPE_VDR12 3
+#define OUTPUT_TYPE_VDR13 4
+
+#define SERVICE_FILTER_TV 1
+#define SERVICE_FILTER_RADIO 2
+#define SERVICE_FILTER_OTHER 4
+#define SERVICE_FILTER_ENCRYPTED 8
+
+#define TIMEOUT_WAIT_LOCK 2
+
+
+// transponders we have yet to scan
+static struct transponder *toscan = NULL;
+static struct transponder *toscan_end = NULL;
+
+// transponders we have scanned
+static struct transponder *scanned = NULL;
+static struct transponder *scanned_end = NULL;
+
+
+static void usage(void)
+{
+ static const char *_usage = "\n"
+ " dvbscan: A digital tv channel scanning utility\n"
+ " Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)\n\n"
+ " usage: dvbscan <options> as follows:\n"
+ " -h help\n"
+ " -adapter <id> adapter to use (default 0)\n"
+ " -frontend <id> frontend to use (default 0)\n"
+ " -demux <id> demux to use (default 0)\n"
+ " -secfile <filename> Optional sec.conf file.\n"
+ " -secid <secid> ID of the SEC configuration to use, one of:\n"
+ " * UNIVERSAL (default) - Europe, 10800 to 11800 MHz and 11600 to 12700 Mhz,\n"
+ " Dual LO, loband 9750, hiband 10600 MHz.\n"
+ " * DBS - Expressvu, North America, 12200 to 12700 MHz, Single LO, 11250 MHz.\n"
+ " * STANDARD - 10945 to 11450 Mhz, Single LO, 10000 Mhz.\n"
+ " * ENHANCED - Astra, 10700 to 11700 MHz, Single LO, 9750 MHz.\n"
+ " * C-BAND - Big Dish, 3700 to 4200 MHz, Single LO, 5150 Mhz.\n"
+ " * C-MULTI - Big Dish - Multipoint LNBf, 3700 to 4200 MHz,\n"
+ " Dual LO, H:5150MHz, V:5750MHz.\n"
+ " * One of the sec definitions from the secfile if supplied\n"
+ " -satpos <position> Specify DISEQC switch position for DVB-S.\n"
+ " -inversion <on|off|auto> Specify inversion (default: auto).\n"
+ " -uk-ordering Use UK DVB-T channel ordering if present.\n"
+ " -timeout <secs> Specify filter timeout to use (standard specced values will be used by default)\n"
+ " -filter <filter> Specify service filter, a comma seperated list of the following tokens:\n"
+ " (If no filter is supplied, all services will be output)\n"
+ " * tv - Output TV channels\n"
+ " * radio - Output radio channels\n"
+ " * other - Output other channels\n"
+ " * encrypted - Output encrypted channels\n"
+ " -out raw <filename>|- Output in raw format to <filename> or stdout\n"
+ " channels <filename>|- Output in channels.conf format to <filename> or stdout.\n"
+ " vdr12 <filename>|- Output in vdr 1.2.x format to <filename> or stdout.\n"
+ " vdr13 <filename>|- Output in vdr 1.3.x format to <filename> or stdout.\n"
+ " <initial scan file>\n";
+ fprintf(stderr, "%s\n", _usage);
+
+ exit(1);
+}
+
+
+static int scan_load_callback(struct dvbcfg_scanfile *channel, void *private_data)
+{
+ struct dvbfe_info *feinfo = (struct dvbfe_info *) private_data;
+
+ if (channel->fe_type != feinfo->type)
+ return 0;
+
+ struct transponder *t = new_transponder();
+ append_transponder(t, &toscan, &toscan_end);
+ memcpy(&t->params, &channel->fe_params, sizeof(struct dvbfe_parameters));
+
+ add_frequency(t, t->params.frequency);
+ t->params.frequency = 0;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ uint32_t i;
+ int argpos = 1;
+ int adapter_id = 0;
+ int frontend_id = 0;
+ int demux_id = 0;
+ char *secfile = NULL;
+ char *secid = NULL;
+ int satpos = 0;
+ enum dvbfe_spectral_inversion inversion = DVBFE_INVERSION_AUTO;
+ int service_filter = -1;
+ int uk_ordering = 0;
+ int timeout = 5;
+ int output_type = OUTPUT_TYPE_RAW;
+ char *output_filename = NULL;
+ char *scan_filename = NULL;
+ struct dvbsec_config sec;
+ int valid_sec = 0;
+
+ while(argpos != argc) {
+ if (!strcmp(argv[argpos], "-h")) {
+ usage();
+ } else if (!strcmp(argv[argpos], "-adapter")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &adapter_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-frontend")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &frontend_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-demux")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &demux_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-secfile")) {
+ if ((argc - argpos) < 2)
+ usage();
+ secfile = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-secid")) {
+ if ((argc - argpos) < 2)
+ usage();
+ secid = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-satpos")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &satpos) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-inversion")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (!strcmp(argv[argpos+1], "off")) {
+ inversion = DVBFE_INVERSION_OFF;
+ } else if (!strcmp(argv[argpos+1], "on")) {
+ inversion = DVBFE_INVERSION_ON;
+ } else if (!strcmp(argv[argpos+1], "auto")) {
+ inversion = DVBFE_INVERSION_AUTO;
+ } else {
+ usage();
+ }
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-uk-ordering")) {
+ if ((argc - argpos) < 1)
+ usage();
+ uk_ordering = 1;
+ } else if (!strcmp(argv[argpos], "-timeout")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &timeout) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-filter")) {
+ if ((argc - argpos) < 2)
+ usage();
+ service_filter = 0;
+ if (!strstr(argv[argpos+1], "tv")) {
+ service_filter |= SERVICE_FILTER_TV;
+ }
+ if (!strstr(argv[argpos+1], "radio")) {
+ service_filter |= SERVICE_FILTER_RADIO;
+ }
+ if (!strstr(argv[argpos+1], "other")) {
+ service_filter |= SERVICE_FILTER_OTHER;
+ }
+ if (!strstr(argv[argpos+1], "encrypted")) {
+ service_filter |= SERVICE_FILTER_ENCRYPTED;
+ }
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-out")) {
+ if ((argc - argpos) < 3)
+ usage();
+ if (!strcmp(argv[argpos+1], "raw")) {
+ output_type = OUTPUT_TYPE_RAW;
+ } else if (!strcmp(argv[argpos+1], "channels")) {
+ output_type = OUTPUT_TYPE_CHANNELS;
+ } else if (!strcmp(argv[argpos+1], "vdr12")) {
+ output_type = OUTPUT_TYPE_VDR12;
+ } else if (!strcmp(argv[argpos+1], "vdr13")) {
+ output_type = OUTPUT_TYPE_VDR13;
+ } else {
+ usage();
+ }
+ output_filename = argv[argpos+2];
+ if (!strcmp(output_filename, "-"))
+ output_filename = NULL;
+ } else {
+ if ((argc - argpos) != 1)
+ usage();
+ scan_filename = argv[argpos];
+ argpos++;
+ }
+ }
+
+ // open the frontend & get its type
+ struct dvbfe_handle *fe = dvbfe_open(adapter_id, frontend_id, 0);
+ if (fe == NULL) {
+ fprintf(stderr, "Failed to open frontend\n");
+ exit(1);
+ }
+ struct dvbfe_info feinfo;
+ if (dvbfe_get_info(fe, 0, &feinfo, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0) != 0) {
+ fprintf(stderr, "Failed to query frontend\n");
+ exit(1);
+ }
+
+ // default SEC with a DVBS card
+ if ((secid == NULL) && (feinfo.type == DVBFE_TYPE_DVBS))
+ secid = "UNIVERSAL";
+
+ // look up SECID if one was supplied
+ if (secid != NULL) {
+ if (dvbsec_cfg_find(secfile, secid, &sec)) {
+ fprintf(stderr, "Unable to find suitable sec/lnb configuration for channel\n");
+ exit(1);
+ }
+ valid_sec = 1;
+ }
+
+ // load the initial scan file
+ FILE *scan_file = fopen(scan_filename, "r");
+ if (scan_file == NULL) {
+ fprintf(stderr, "Could not open scan file %s\n", scan_filename);
+ exit(1);
+ }
+ if (dvbcfg_scanfile_parse(scan_file, scan_load_callback, &feinfo) < 0) {
+ fprintf(stderr, "Could not parse scan file %s\n", scan_filename);
+ exit(1);
+ }
+ fclose(scan_file);
+
+ // main scan loop
+ while(toscan) {
+ // get the first item on the toscan list
+ struct transponder *tmp = first_transponder(&toscan, &toscan_end);
+
+ // have we already seen this transponder?
+ if (seen_transponder(tmp, scanned)) {
+ free_transponder(tmp);
+ continue;
+ }
+
+ // do we have a valid SEC configuration?
+ struct dvbsec_config *psec = NULL;
+ if (valid_sec)
+ psec = &sec;
+
+ // tune it
+ int tuned_ok = 0;
+ for(i=0; i < tmp->frequency_count; i++) {
+ tmp->params.frequency = tmp->frequencies[i];
+ if (dvbsec_set(fe,
+ psec,
+ tmp->polarization,
+ (satpos & 0x01) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
+ (satpos & 0x02) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
+ &tmp->params,
+ 0)) {
+ fprintf(stderr, "Failed to set frontend\n");
+ exit(1);
+ }
+
+ // wait for lock
+ time_t starttime = time(NULL);
+ while((time(NULL) - starttime) < TIMEOUT_WAIT_LOCK) {
+ if (dvbfe_get_info(fe, DVBFE_INFO_LOCKSTATUS, &feinfo,
+ DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0) !=
+ DVBFE_INFO_QUERYTYPE_IMMEDIATE) {
+ fprintf(stderr, "Unable to query frontend status\n");
+ exit(1);
+ }
+ if (feinfo.lock) {
+ tuned_ok = 1;
+ break;
+ }
+ usleep(100000);
+ }
+ }
+ if (!tuned_ok) {
+ free_transponder(tmp);
+ continue;
+ }
+
+ // scan it
+ switch(feinfo.type) {
+ case DVBFE_TYPE_DVBS:
+ case DVBFE_TYPE_DVBC:
+ case DVBFE_TYPE_DVBT:
+ dvbscan_scan_dvb(fe);
+ break;
+
+ case DVBFE_TYPE_ATSC:
+ dvbscan_scan_atsc(fe);
+ break;
+ }
+
+ // add to scanned list.
+ append_transponder(tmp, &scanned, &scanned_end);
+ }
+
+ // FIXME: output the data
+
+ return 0;
+}
+
+int create_section_filter(int adapter, int demux, uint16_t pid, uint8_t table_id)
+{
+ int demux_fd = -1;
+ uint8_t filter[18];
+ uint8_t mask[18];
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ return -1;
+ }
+
+ // create a section filter
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = table_id;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(demux_fd, pid, filter, mask, 1, 1)) {
+ close(demux_fd);
+ return -1;
+ }
+
+ // done
+ return demux_fd;
+}
diff --git a/util/dvbscan/dvbscan.h b/util/dvbscan/dvbscan.h
new file mode 100644
index 0000000..ddf61cf
--- /dev/null
+++ b/util/dvbscan/dvbscan.h
@@ -0,0 +1,136 @@
+/*
+ dvbscan utility
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef DVBSCAN_H
+#define DVBSCAN_H 1
+
+#include <libdvbapi/dvbfe.h>
+#include <libdvbsec/dvbsec_api.h>
+#include <libucsi/types.h>
+
+/**
+ * A stream which is part of a service.
+ */
+struct stream
+{
+ uint8_t stream_type;
+ iso639lang_t language;
+
+ struct stream *next;
+};
+
+/**
+ * A service (programme) which is part of a transponder.
+ */
+struct service
+{
+ /**
+ * Service identification stuff. Strings are in UTF-8.
+ */
+ uint16_t service_id;
+ char *provider_name;
+ char *service_name;
+
+ /**
+ * Pids common to the whole service.
+ */
+ uint16_t pmt_pid;
+ uint16_t pcr_pid;
+
+ /**
+ * CA stuff.
+ */
+ uint16_t *ca_ids;
+ uint32_t ca_ids_count;
+ uint8_t is_scrambled;
+
+ /**
+ * BBC channel number (-1 if unknown).
+ */
+ int bbc_channel_number;
+
+ /**
+ * Streams composing this service.
+ */
+ struct stream *streams;
+ struct stream *streams_end;
+
+ /**
+ * Next service in list.
+ */
+ struct service *next;
+};
+
+/**
+ * A collection of multiplexed services.
+ */
+struct transponder
+{
+ /**
+ * we need to have a seperate list of frequencies since the
+ * DVB standard allows a frequency list descriptor of alternate
+ * frequencies to be supplied.
+ */
+ uint32_t *frequencies;
+ uint32_t frequency_count;
+
+ /**
+ * The rest of the tuning parameters.
+ */
+ struct dvbfe_parameters params;
+
+ /**
+ * DVBS specific parameters
+ */
+ enum dvbsec_diseqc_polarization polarization;
+ int oribital_position;
+
+ /**
+ * Numerical IDs
+ */
+ uint16_t network_id;
+ uint16_t original_network_id;
+ uint16_t transport_stream_id;
+
+ /**
+ * Services detected on this transponder.
+ */
+ struct service *services;
+ struct service *services_end;
+
+ /**
+ * Next item in list.
+ */
+ struct transponder *next;
+};
+
+extern void append_transponder(struct transponder *t, struct transponder **tlist, struct transponder **tlist_end);
+extern struct transponder *new_transponder(void);
+extern void free_transponder(struct transponder *t);
+extern int seen_transponder(struct transponder *t, struct transponder *checklist);
+extern void add_frequency(struct transponder *t, uint32_t frequency);
+extern struct transponder *first_transponder(struct transponder **tlist, struct transponder **tlist_end);
+
+extern int create_section_filter(int adapter, int demux, uint16_t pid, uint8_t table_id);
+extern void dvbscan_scan_dvb(struct dvbfe_handle *fe);
+extern void dvbscan_scan_atsc(struct dvbfe_handle *fe);
+
+#endif
diff --git a/util/dvbscan/dvbscan_atsc.c b/util/dvbscan/dvbscan_atsc.c
new file mode 100644
index 0000000..b346f78
--- /dev/null
+++ b/util/dvbscan/dvbscan_atsc.c
@@ -0,0 +1,30 @@
+/*
+ dvbscan utility
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "dvbscan.h"
+
+void dvbscan_scan_atsc(struct dvbfe_handle *fe)
+{
+ // FIXME
+}
diff --git a/util/dvbscan/dvbscan_dvb.c b/util/dvbscan/dvbscan_dvb.c
new file mode 100644
index 0000000..c76d072
--- /dev/null
+++ b/util/dvbscan/dvbscan_dvb.c
@@ -0,0 +1,30 @@
+/*
+ dvbscan utility
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "dvbscan.h"
+
+void dvbscan_scan_dvb(struct dvbfe_handle *fe)
+{
+ // FIXME
+}
diff --git a/util/dvbscan/dvbscan_structutils.c b/util/dvbscan/dvbscan_structutils.c
new file mode 100644
index 0000000..6fe3124
--- /dev/null
+++ b/util/dvbscan/dvbscan_structutils.c
@@ -0,0 +1,99 @@
+/*
+ dvbscan utility
+
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "dvbscan.h"
+
+void append_transponder(struct transponder *t, struct transponder **tlist, struct transponder **tlist_end)
+{
+ if (*tlist_end == NULL) {
+ *tlist = t;
+ } else {
+ (*tlist_end)->next = t;
+ }
+ *tlist_end = t;
+ t->next = NULL;
+}
+
+struct transponder *new_transponder(void)
+{
+ struct transponder *t = (struct transponder *) malloc(sizeof(struct transponder));
+ if (t == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ memset(t, 0, sizeof(struct transponder));
+
+ return t;
+}
+
+void free_transponder(struct transponder *t)
+{
+ if (t->frequencies)
+ free(t->frequencies);
+ // FIXME: free services
+ free(t);
+}
+
+int seen_transponder(struct transponder *t, struct transponder *checklist)
+{
+ uint32_t i;
+
+ struct transponder *cur_check = checklist;
+ while(cur_check) {
+ uint32_t freq1 = cur_check->params.frequency / 2000;
+ for(i=0; i < t->frequency_count; i++) {
+ uint32_t freq2 = t->frequencies[i] / 2000;
+ if (freq1 == freq2) {
+ return 1;
+ }
+ }
+ cur_check = cur_check->next;
+ }
+
+ return 0;
+}
+
+void add_frequency(struct transponder *t, uint32_t frequency)
+{
+ uint32_t *tmp;
+
+ tmp = (uint32_t*) realloc(t->frequencies, sizeof(uint32_t) * (t->frequency_count + 1));
+ if (tmp == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ tmp[t->frequency_count++] = frequency;
+ t->frequencies = tmp;
+}
+
+struct transponder *first_transponder(struct transponder **tlist, struct transponder **tlist_end)
+{
+ struct transponder *t = *tlist;
+
+ *tlist = t->next;
+ if (*tlist == NULL)
+ *tlist_end = NULL;
+
+ return t;
+}
diff --git a/util/dvbtraffic/Makefile b/util/dvbtraffic/Makefile
index c29be40..b9a8e82 100644
--- a/util/dvbtraffic/Makefile
+++ b/util/dvbtraffic/Makefile
@@ -1,6 +1,15 @@
+# Makefile for linuxtv.org dvb-apps/util/dvbtraffic
-dvbtraffic: dvbtraffic.c
- gcc -MD -g -O2 -Wall -I../../include $< -o $@
+binaries = dvbtraffic
-clean:
- rm -f *.o *.d dvbtraffic
+inst_bin = $(binaries)
+
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi
+LDLIBS += -ldvbapi
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/util/dvbtraffic/dvbtraffic.c b/util/dvbtraffic/dvbtraffic.c
index 8add053..b9a151d 100644
--- a/util/dvbtraffic/dvbtraffic.c
+++ b/util/dvbtraffic/dvbtraffic.c
@@ -1,3 +1,5 @@
+/* This file is released into the public domain by its authors */
+
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
@@ -9,64 +11,83 @@
#include <sys/poll.h>
#include <sys/time.h>
#include <string.h>
-
-#include <linux/dvb/dmx.h>
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/video.h>
+#include <limits.h>
+#include <libdvbapi/dvbdemux.h>
#define BSIZE 188
-int pidt[0x2001];
+static int pidt[0x2001];
+
+static void usage(FILE *output)
+{
+ fprintf(output,
+ "Usage: dvbtraffic [OPTION]...\n"
+ "Options:\n"
+ " -a N use dvb adapter N\n"
+ " -d N use demux N\n"
+ " -h display this help\n");
+}
int main(int argc, char **argv)
{
- int fd, ffd, packets = 0;
struct timeval startt;
- struct dmx_pes_filter_params flt;
- char *search;
- unsigned char buffer[BSIZE];
-
- fd = open("/dev/dvb/adapter0/dvr0", O_RDONLY);
-
- ioctl(fd, DMX_SET_BUFFER_SIZE, 1024 * 1024);
+ int adapter = 0, demux = 0;
+ char *search = NULL;
+ int fd, ffd, packets = 0;
+ int opt;
- ffd = open("/dev/dvb/adapter0/demux0", O_RDWR);
- if (ffd < 0) {
- perror("/dev/dvb/adapter0/demux0");
- return -fd;
+ while ((opt = getopt(argc, argv, "a:d:hs:")) != -1) {
+ switch (opt) {
+ case 'a':
+ adapter = atoi(optarg);
+ break;
+ case 'd':
+ demux = atoi(optarg);
+ break;
+ case 'h':
+ usage(stdout);
+ exit(0);
+ case 's':
+ search = strdup(optarg);
+ break;
+ default:
+ usage(stderr);
+ exit(1);
+ }
}
- flt.pid = 0x2000;
- flt.input = DMX_IN_FRONTEND;
- flt.output = DMX_OUT_TS_TAP;
- flt.pes_type = DMX_PES_OTHER;
- flt.flags = 0;
+ // open the DVR device
+ fd = dvbdemux_open_dvr(adapter, demux, 1, 0);
+ if (fd < 0) {
+ fprintf(stderr, "dvbtraffic: Could not open dvr device: %m\n");
+ exit(1);
+ }
+ dvbdemux_set_buffer(fd, 1024 * 1024);
- if (ioctl(ffd, DMX_SET_PES_FILTER, &flt) < 0) {
- perror("DMX_SET_PES_FILTER");
- return -1;
+ ffd = dvbdemux_open_demux(adapter, demux, 0);
+ if (ffd < 0) {
+ fprintf(stderr, "dvbtraffic: Could not open demux device: %m\n");
+ exit(1);
}
- if (ioctl(ffd, DMX_START, 0) < 0) {
- perror("DMX_SET_PES_FILTER");
+ if (dvbdemux_set_pid_filter(ffd, -1, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DVR, 1)) {
+ perror("dvbdemux_set_pid_filter");
return -1;
}
gettimeofday(&startt, 0);
- if (argc > 1)
- search = argv[1];
- else
- search = 0;
-
while (1) {
- int pid, r, ok;
- if ((r = read(fd, buffer, 188)) <= 0) {
+ unsigned char buffer[BSIZE];
+ int pid, ok;
+ ssize_t r;
+
+ if ((r = read(fd, buffer, BSIZE)) <= 0) {
perror("read");
break;
}
- if (r != 188) {
- printf("only read %d\n", r);
+ if (r != BSIZE) {
+ fprintf(stderr, "dvbtraffic: only read %zd bytes\n", r);
break;
}
if (buffer[0] != 0x47) {
@@ -106,16 +127,16 @@ int main(int argc, char **argv)
(now.tv_sec - startt.tv_sec) * 1000 +
(now.tv_usec - startt.tv_usec) / 1000;
if (diff > 1000) {
- int pid = 0;
- for (pid = 0; pid < 0x2001; pid++) {
- if (pidt[pid]) {
+ int _pid = 0;
+ for (_pid = 0; _pid < 0x2001; _pid++) {
+ if (pidt[_pid]) {
printf("%04x %5d p/s %5d kb/s %5d kbit\n",
- pid,
- pidt[pid] * 1000 / diff,
- pidt[pid] * 1000 / diff * 188 / 1024,
- pidt[pid] * 8 * 1000 / diff * 188 / 1000);
+ _pid,
+ pidt[_pid] * 1000 / diff,
+ pidt[_pid] * 1000 / diff * 188 / 1024,
+ pidt[_pid] * 8 * 1000 / diff * 188 / 1000);
}
- pidt[pid] = 0;
+ pidt[_pid] = 0;
}
printf("-PID--FREQ-----BANDWIDTH-BANDWIDTH-\n");
startt = now;
@@ -127,4 +148,3 @@ int main(int argc, char **argv)
close(fd);
return 0;
}
-
diff --git a/util/femon/Makefile b/util/femon/Makefile
new file mode 100644
index 0000000..4381d43
--- /dev/null
+++ b/util/femon/Makefile
@@ -0,0 +1,15 @@
+# Makefile for linuxtv.org dvb-apps/util/femon
+
+binaries = femon
+
+inst_bin = $(binaries)
+
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi
+LDLIBS += -ldvbapi
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/util/femon/femon.c b/util/femon/femon.c
new file mode 100644
index 0000000..46d239d
--- /dev/null
+++ b/util/femon/femon.c
@@ -0,0 +1,175 @@
+/* femon -- monitor frontend status
+ *
+ * Copyright (C) 2003 convergence GmbH
+ * Johannes Stezenbach <js@convergence.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <stdint.h>
+#include <sys/time.h>
+
+#include <libdvbapi/dvbfe.h>
+
+#define FE_STATUS_PARAMS (DVBFE_INFO_LOCKSTATUS|DVBFE_INFO_SIGNAL_STRENGTH|DVBFE_INFO_BER|DVBFE_INFO_SNR|DVBFE_INFO_UNCORRECTED_BLOCKS)
+
+static char *usage_str =
+ "\nusage: femon [options]\n"
+ " -H : human readable output\n"
+ " -a number : use given adapter (default 0)\n"
+ " -f number : use given frontend (default 0)\n"
+ " -c number : samples to take (default 0 = infinite)\n\n";
+
+
+static void usage(void)
+{
+ fprintf(stderr, usage_str);
+ exit(1);
+}
+
+
+static
+int check_frontend (struct dvbfe_handle *fe, int human_readable, unsigned int count)
+{
+ struct dvbfe_info fe_info;
+ unsigned int samples = 0;
+
+ do {
+ if (dvbfe_get_info(fe, FE_STATUS_PARAMS, &fe_info, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0) != FE_STATUS_PARAMS) {
+ fprintf(stderr, "Problem retrieving frontend information: %m\n");
+ }
+
+
+
+ if (human_readable) {
+ printf ("status %c%c%c%c%c | signal %3u%% | snr %3u%% | ber %d | unc %d | ",
+ fe_info.signal ? 'S' : ' ',
+ fe_info.carrier ? 'C' : ' ',
+ fe_info.viterbi ? 'V' : ' ',
+ fe_info.sync ? 'Y' : ' ',
+ fe_info.lock ? 'L' : ' ',
+ (fe_info.signal_strength * 100) / 0xffff,
+ (fe_info.snr * 100) / 0xffff,
+ fe_info.ber,
+ fe_info.ucblocks);
+ } else {
+ printf ("status %c%c%c%c%c | signal %04x | snr %04x | ber %08x | unc %08x | ",
+ fe_info.signal ? 'S' : ' ',
+ fe_info.carrier ? 'C' : ' ',
+ fe_info.viterbi ? 'V' : ' ',
+ fe_info.sync ? 'Y' : ' ',
+ fe_info.lock ? 'L' : ' ',
+ fe_info.signal_strength,
+ fe_info.snr,
+ fe_info.ber,
+ fe_info.ucblocks);
+ }
+
+ if (fe_info.lock)
+ printf("FE_HAS_LOCK");
+
+ printf("\n");
+ fflush(stdout);
+ usleep(1000000);
+ samples++;
+ } while ((!count) || (count-samples));
+
+ return 0;
+}
+
+
+static
+int do_mon(unsigned int adapter, unsigned int frontend, int human_readable, unsigned int count)
+{
+ int result;
+ struct dvbfe_handle *fe;
+ struct dvbfe_info fe_info;
+ char *fe_type = "UNKNOWN";
+
+ fe = dvbfe_open(adapter, frontend, 1);
+ if (fe == NULL) {
+ perror("opening frontend failed");
+ return 0;
+ }
+
+ dvbfe_get_info(fe, 0, &fe_info, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
+ switch(fe_info.type) {
+ case DVBFE_TYPE_DVBS:
+ fe_type = "DVBS";
+ break;
+ case DVBFE_TYPE_DVBC:
+ fe_type = "DVBC";
+ break;
+ case DVBFE_TYPE_DVBT:
+ fe_type = "DVBT";
+ break;
+ case DVBFE_TYPE_ATSC:
+ fe_type = "ATSC";
+ break;
+ }
+ printf("FE: %s (%s)\n", fe_info.name, fe_type);
+
+ result = check_frontend (fe, human_readable, count);
+
+ dvbfe_close(fe);
+
+ return result;
+}
+
+int main(int argc, char *argv[])
+{
+ unsigned int adapter = 0, frontend = 0, count = 0;
+ int human_readable = 0;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "Ha:f:c:")) != -1) {
+ switch (opt)
+ {
+ default:
+ usage();
+ break;
+ case 'a':
+ adapter = strtoul(optarg, NULL, 0);
+ break;
+ case 'c':
+ count = strtoul(optarg, NULL, 0);
+ break;
+ case 'f':
+ frontend = strtoul(optarg, NULL, 0);
+ break;
+ case 'H':
+ human_readable = 1;
+ break;
+ }
+ }
+
+ do_mon(adapter, frontend, human_readable, count);
+
+ return 0;
+}
diff --git a/util/gnutv/Makefile b/util/gnutv/Makefile
new file mode 100644
index 0000000..3a679c4
--- /dev/null
+++ b/util/gnutv/Makefile
@@ -0,0 +1,21 @@
+# Makefile for linuxtv.org dvb-apps/util/gnutv
+
+objects = gnutv_ca.o \
+ gnutv_dvb.o \
+ gnutv_data.o
+
+binaries = gnutv
+
+inst_bin = $(binaries)
+
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi -L../../lib/libdvbcfg -L../../lib/libdvbsec -L../../lib/libdvben50221 -L../../lib/libucsi
+LDLIBS += -ldvbcfg -ldvben50221 -lucsi -ldvbsec -ldvbapi -lpthread
+
+.PHONY: all
+
+all: $(binaries)
+
+$(binaries): $(objects)
+
+include ../../Make.rules
diff --git a/util/gnutv/gnutv.c b/util/gnutv/gnutv.c
new file mode 100644
index 0000000..62f19be
--- /dev/null
+++ b/util/gnutv/gnutv.c
@@ -0,0 +1,365 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/poll.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libdvbapi/dvbaudio.h>
+#include <libdvbsec/dvbsec_cfg.h>
+#include <libucsi/mpeg/section.h>
+#include "gnutv.h"
+#include "gnutv_dvb.h"
+#include "gnutv_ca.h"
+#include "gnutv_data.h"
+
+
+static void signal_handler(int _signal);
+
+static int quit_app = 0;
+
+void usage(void)
+{
+ static const char *_usage = "\n"
+ " gnutv: A digital tv utility\n"
+ " Copyright (C) 2004, 2005, 2006 Manu Abraham (manu@kromtek.com)\n"
+ " Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)\n\n"
+ " usage: gnutv <options> as follows:\n"
+ " -h help\n"
+ " -adapter <id> adapter to use (default 0)\n"
+ " -frontend <id> frontend to use (default 0)\n"
+ " -demux <id> demux to use (default 0)\n"
+ " -caslotnum <id> ca slot number to use (default 0)\n"
+ " -channels <filename> channels.conf file.\n"
+ " -secfile <filename> Optional sec.conf file.\n"
+ " -secid <secid> ID of the SEC configuration to use, one of:\n"
+ " * UNIVERSAL (default) - Europe, 10800 to 11800 MHz and 11600 to 12700 Mhz,\n"
+ " Dual LO, loband 9750, hiband 10600 MHz.\n"
+ " * DBS - Expressvu, North America, 12200 to 12700 MHz, Single LO, 11250 MHz.\n"
+ " * STANDARD - 10945 to 11450 Mhz, Single LO, 10000 Mhz.\n"
+ " * ENHANCED - Astra, 10700 to 11700 MHz, Single LO, 9750 MHz.\n"
+ " * C-BAND - Big Dish, 3700 to 4200 MHz, Single LO, 5150 Mhz.\n"
+ " * C-MULTI - Big Dish - Multipoint LNBf, 3700 to 4200 MHz,\n"
+ " Dual LO, H:5150MHz, V:5750MHz.\n"
+ " * One of the sec definitions from the secfile if supplied\n"
+ " -out decoder Output to hardware decoder (default)\n"
+ " decoderabypass Output to hardware decoder using audio bypass\n"
+ " dvr Output stream to dvr device\n"
+ " null Do not output anything\n"
+ " stdout Output to stdout\n"
+ " file <filename> Output stream to file\n"
+ " udp <address> <port> Output stream to address:port using udp\n"
+ " udpif <address> <port> <interface> Output stream to address:port using udp\n"
+ " forcing the specified interface\n"
+ " rtp <address> <port> Output stream to address:port using udp-rtp\n"
+ " rtpif <address> <port> <interface> Output stream to address:port using udp-rtp\n"
+ " forcing the specified interface\n"
+ " -timeout <secs> Number of seconds to output channel for\n"
+ " (0=>exit immediately after successful tuning, default is to output forever)\n"
+ " -cammenu Show the CAM menu\n"
+ " -nomoveca Do not attempt to move CA descriptors from stream to programme level\n"
+ " <channel name>\n";
+ fprintf(stderr, "%s\n", _usage);
+
+ exit(1);
+}
+
+int find_channel(struct dvbcfg_zapchannel *channel, void *private_data)
+{
+ struct dvbcfg_zapchannel *tmpchannel = private_data;
+
+ if (strcmp(channel->name, tmpchannel->name) == 0) {
+ memcpy(tmpchannel, channel, sizeof(struct dvbcfg_zapchannel));
+ return 1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int adapter_id = 0;
+ int frontend_id = 0;
+ int demux_id = 0;
+ int caslot_num = 0;
+ char *chanfile = "/etc/channels.conf";
+ char *secfile = NULL;
+ char *secid = NULL;
+ char *channel_name = NULL;
+ int output_type = OUTPUT_TYPE_DECODER;
+ char *outfile = NULL;
+ char *outhost = NULL;
+ char *outport = NULL;
+ char *outif = NULL;
+ struct addrinfo *outaddrs = NULL;
+ int timeout = -1;
+ int moveca = 1;
+ int cammenu = 0;
+ int argpos = 1;
+ struct gnutv_dvb_params gnutv_dvb_params;
+ struct gnutv_ca_params gnutv_ca_params;
+ int ffaudiofd = -1;
+ int usertp = 0;
+
+ while(argpos != argc) {
+ if (!strcmp(argv[argpos], "-h")) {
+ usage();
+ } else if (!strcmp(argv[argpos], "-adapter")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &adapter_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-frontend")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &frontend_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-demux")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &demux_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-caslotnum")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &caslot_num) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-channels")) {
+ if ((argc - argpos) < 2)
+ usage();
+ chanfile = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-secfile")) {
+ if ((argc - argpos) < 2)
+ usage();
+ secfile = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-secid")) {
+ if ((argc - argpos) < 2)
+ usage();
+ secid = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-out")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (!strcmp(argv[argpos+1], "decoder")) {
+ output_type = OUTPUT_TYPE_DECODER;
+ } else if (!strcmp(argv[argpos+1], "decoderabypass")) {
+ output_type = OUTPUT_TYPE_DECODER_ABYPASS;
+ } else if (!strcmp(argv[argpos+1], "dvr")) {
+ output_type = OUTPUT_TYPE_DVR;
+ } else if (!strcmp(argv[argpos+1], "null")) {
+ output_type = OUTPUT_TYPE_NULL;
+ } else if (!strcmp(argv[argpos+1], "stdout")) {
+ output_type = OUTPUT_TYPE_STDOUT;
+ } else if (!strcmp(argv[argpos+1], "file")) {
+ output_type = OUTPUT_TYPE_FILE;
+ if ((argc - argpos) < 3)
+ usage();
+ outfile = argv[argpos+2];
+ argpos++;
+ } else if ((!strcmp(argv[argpos+1], "udp")) ||
+ (!strcmp(argv[argpos+1], "rtp"))) {
+ output_type = OUTPUT_TYPE_UDP;
+ if ((argc - argpos) < 4)
+ usage();
+
+ if (!strcmp(argv[argpos+1], "rtp"))
+ usertp = 1;
+ outhost = argv[argpos+2];
+ outport = argv[argpos+3];
+ argpos+=2;
+ } else if ((!strcmp(argv[argpos+1], "udpif")) ||
+ (!strcmp(argv[argpos+1], "rtpif"))) {
+ output_type = OUTPUT_TYPE_UDP;
+ if ((argc - argpos) < 5)
+ usage();
+
+ if (!strcmp(argv[argpos+1], "rtpif"))
+ usertp = 1;
+ outhost = argv[argpos+2];
+ outport = argv[argpos+3];
+ outif = argv[argpos+4];
+ argpos+=3;
+ } else {
+ usage();
+ }
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-timeout")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &timeout) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-nomoveca")) {
+ moveca = 0;
+ argpos++;
+ } else if (!strcmp(argv[argpos], "-cammenu")) {
+ cammenu = 1;
+ argpos++;
+ } else {
+ if ((argc - argpos) != 1)
+ usage();
+ channel_name = argv[argpos];
+ argpos++;
+ }
+ }
+
+ // the user didn't select anything!
+ if ((channel_name == NULL) && (!cammenu))
+ usage();
+
+ // resolve host/port
+ if ((outhost != NULL) && (outport != NULL)) {
+ int res;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ if ((res = getaddrinfo(outhost, outport, &hints, &outaddrs)) != 0) {
+ fprintf(stderr, "Unable to resolve requested address: %s\n", gai_strerror(res));
+ exit(1);
+ }
+ }
+
+ // setup any signals
+ signal(SIGINT, signal_handler);
+ signal(SIGPIPE, SIG_IGN);
+
+ // start the CA stuff
+ gnutv_ca_params.adapter_id = adapter_id;
+ gnutv_ca_params.caslot_num = caslot_num;
+ gnutv_ca_params.cammenu = cammenu;
+ gnutv_ca_params.moveca = moveca;
+ gnutv_ca_start(&gnutv_ca_params);
+
+ // frontend setup if a channel name was supplied
+ if ((!cammenu) && (channel_name != NULL)) {
+ // find the requested channel
+ if (strlen(channel_name) >= sizeof(gnutv_dvb_params.channel.name)) {
+ fprintf(stderr, "Channel name is too long %s\n", channel_name);
+ exit(1);
+ }
+ FILE *channel_file = fopen(chanfile, "r");
+ if (channel_file == NULL) {
+ fprintf(stderr, "Could open channel file %s\n", chanfile);
+ exit(1);
+ }
+ memcpy(gnutv_dvb_params.channel.name, channel_name, strlen(channel_name) + 1);
+ if (dvbcfg_zapchannel_parse(channel_file, find_channel, &gnutv_dvb_params.channel) != 1) {
+ fprintf(stderr, "Unable to find requested channel %s\n", channel_name);
+ exit(1);
+ }
+ fclose(channel_file);
+
+ // default SEC with a DVBS card
+ if ((secid == NULL) && (gnutv_dvb_params.channel.fe_type == DVBFE_TYPE_DVBS))
+ secid = "UNIVERSAL";
+
+ // look it up if one were supplied
+ gnutv_dvb_params.valid_sec = 0;
+ if (secid != NULL) {
+ if (dvbsec_cfg_find(secfile, secid,
+ &gnutv_dvb_params.sec)) {
+ fprintf(stderr, "Unable to find suitable sec/lnb configuration for channel\n");
+ exit(1);
+ }
+ gnutv_dvb_params.valid_sec = 1;
+ }
+
+ // open the frontend
+ gnutv_dvb_params.fe = dvbfe_open(adapter_id, frontend_id, 0);
+ if (gnutv_dvb_params.fe == NULL) {
+ fprintf(stderr, "Failed to open frontend\n");
+ exit(1);
+ }
+
+ // failover decoder to dvr output if decoder not available
+ if ((output_type == OUTPUT_TYPE_DECODER) ||
+ (output_type == OUTPUT_TYPE_DECODER_ABYPASS)) {
+ ffaudiofd = dvbaudio_open(adapter_id, 0);
+ if (ffaudiofd < 0) {
+ fprintf(stderr, "Cannot open decoder; defaulting to dvr output\n");
+ output_type = OUTPUT_TYPE_DVR;
+ }
+ }
+
+ // start the DVB stuff
+ gnutv_dvb_params.adapter_id = adapter_id;
+ gnutv_dvb_params.frontend_id = frontend_id;
+ gnutv_dvb_params.demux_id = demux_id;
+ gnutv_dvb_params.output_type = output_type;
+ gnutv_dvb_start(&gnutv_dvb_params);
+
+ // start the data stuff
+ gnutv_data_start(output_type, ffaudiofd, adapter_id, demux_id, outfile, outif, outaddrs, usertp);
+ }
+
+ // the UI
+ time_t start = 0;
+ while(!quit_app) {
+ if (gnutv_dvb_locked() && (start == 0))
+ start = time(NULL);
+
+ // the timeout
+ if ((timeout != -1) && (start != 0)) {
+ if ((time(NULL) - start) >= timeout)
+ break;
+ }
+
+ if (cammenu)
+ gnutv_ca_ui();
+ else
+ usleep(1);
+ }
+
+ // stop data handling
+ gnutv_data_stop();
+
+ // shutdown DVB stuff
+ if (channel_name != NULL)
+ gnutv_dvb_stop();
+
+ // shutdown CA stuff
+ gnutv_ca_stop();
+
+ // done
+ exit(0);
+}
+
+static void signal_handler(int _signal)
+{
+ (void) _signal;
+
+ if (!quit_app) {
+ quit_app = 1;
+ }
+}
diff --git a/util/gnutv/gnutv.h b/util/gnutv/gnutv.h
new file mode 100644
index 0000000..02ed041
--- /dev/null
+++ b/util/gnutv/gnutv.h
@@ -0,0 +1,37 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __CA_gnutv_H__
+#define __CA_gnutv_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#define OUTPUT_TYPE_DECODER 0
+#define OUTPUT_TYPE_DECODER_ABYPASS 1
+#define OUTPUT_TYPE_DVR 2
+#define OUTPUT_TYPE_NULL 3
+#define OUTPUT_TYPE_FILE 4
+#define OUTPUT_TYPE_UDP 5
+#define OUTPUT_TYPE_STDOUT 6
+
+#endif
diff --git a/util/gnutv/gnutv_ca.c b/util/gnutv/gnutv_ca.c
new file mode 100644
index 0000000..5830f21
--- /dev/null
+++ b/util/gnutv/gnutv_ca.c
@@ -0,0 +1,404 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <pthread.h>
+#include <libdvben50221/en50221_stdcam.h>
+#include "gnutv.h"
+#include "gnutv_ca.h"
+
+
+
+#define MMI_STATE_CLOSED 0
+#define MMI_STATE_OPEN 1
+#define MMI_STATE_ENQ 2
+#define MMI_STATE_MENU 3
+
+static int gnutv_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids);
+static int gnutv_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string);
+
+static int gnutv_mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t delay);
+static int gnutv_mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t mmi_mode);
+static int gnutv_mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t blind_answer, uint8_t expected_answer_length,
+ uint8_t *text, uint32_t text_size);
+static int gnutv_mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw);
+static void *camthread_func(void* arg);
+
+static struct en50221_transport_layer *tl = NULL;
+static struct en50221_session_layer *sl = NULL;
+static struct en50221_stdcam *stdcam = NULL;
+
+static int ca_resource_connected = 0;
+static int mmi_state = MMI_STATE_CLOSED;
+static int mmi_enq_blind;
+static int mmi_enq_length;
+
+static int camthread_shutdown = 0;
+static pthread_t camthread;
+int moveca = 0;
+int seenpmt = 0;
+int cammenu = 0;
+
+char ui_line[256];
+uint32_t ui_linepos = 0;
+
+
+void gnutv_ca_start(struct gnutv_ca_params *params)
+{
+ // create transport layer
+ tl = en50221_tl_create(1, 16);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ return;
+ }
+
+ // create session layer
+ sl = en50221_sl_create(tl, 16);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ en50221_tl_destroy(tl);
+ return;
+ }
+
+ // create the stdcam instance
+ stdcam = en50221_stdcam_create(params->adapter_id, params->caslot_num, tl, sl);
+ if (stdcam == NULL) {
+ en50221_sl_destroy(sl);
+ en50221_tl_destroy(tl);
+ return;
+ }
+
+ // hook up the AI callbacks
+ if (stdcam->ai_resource) {
+ en50221_app_ai_register_callback(stdcam->ai_resource, gnutv_ai_callback, stdcam);
+ }
+
+ // hook up the CA callbacks
+ if (stdcam->ca_resource) {
+ en50221_app_ca_register_info_callback(stdcam->ca_resource, gnutv_ca_info_callback, stdcam);
+ }
+
+ // hook up the MMI callbacks
+ if (params->cammenu) {
+ if (stdcam->mmi_resource) {
+ en50221_app_mmi_register_close_callback(stdcam->mmi_resource, gnutv_mmi_close_callback, stdcam);
+ en50221_app_mmi_register_display_control_callback(stdcam->mmi_resource, gnutv_mmi_display_control_callback, stdcam);
+ en50221_app_mmi_register_enq_callback(stdcam->mmi_resource, gnutv_mmi_enq_callback, stdcam);
+ en50221_app_mmi_register_menu_callback(stdcam->mmi_resource, gnutv_mmi_menu_callback, stdcam);
+ en50221_app_mmi_register_list_callback(stdcam->mmi_resource, gnutv_mmi_menu_callback, stdcam);
+ } else {
+ fprintf(stderr, "CAM Menus are not supported by this interface hardware\n");
+ exit(1);
+ }
+ }
+
+ // any other stuff
+ moveca = params->moveca;
+ cammenu = params->cammenu;
+
+ // start the cam thread
+ pthread_create(&camthread, NULL, camthread_func, NULL);
+}
+
+void gnutv_ca_stop(void)
+{
+ if (stdcam == NULL)
+ return;
+
+ // shutdown the cam thread
+ camthread_shutdown = 1;
+ pthread_join(camthread, NULL);
+
+ // destroy the stdcam
+ if (stdcam->destroy)
+ stdcam->destroy(stdcam, 1);
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+}
+
+void gnutv_ca_ui(void)
+{
+ // make up polling structure for stdin
+ struct pollfd pollfd;
+ pollfd.fd = 0;
+ pollfd.events = POLLIN|POLLPRI|POLLERR;
+
+ if (stdcam == NULL)
+ return;
+
+ // is there a character?
+ if (poll(&pollfd, 1, 10) != 1)
+ return;
+ if (pollfd.revents & POLLERR)
+ return;
+
+ // try to read the character
+ char c;
+ if (read(0, &c, 1) != 1)
+ return;
+ if (c == '\r') {
+ return;
+ } else if (c == '\n') {
+ switch(mmi_state) {
+ case MMI_STATE_CLOSED:
+ case MMI_STATE_OPEN:
+ if ((ui_linepos == 0) && (ca_resource_connected)) {
+ en50221_app_ai_entermenu(stdcam->ai_resource, stdcam->ai_session_number);
+ }
+ break;
+
+ case MMI_STATE_ENQ:
+ if (ui_linepos == 0) {
+ en50221_app_mmi_answ(stdcam->mmi_resource, stdcam->mmi_session_number,
+ MMI_ANSW_ID_CANCEL, NULL, 0);
+ } else {
+ en50221_app_mmi_answ(stdcam->mmi_resource, stdcam->mmi_session_number,
+ MMI_ANSW_ID_ANSWER, (uint8_t*) ui_line, ui_linepos);
+ }
+ mmi_state = MMI_STATE_OPEN;
+ break;
+
+ case MMI_STATE_MENU:
+ ui_line[ui_linepos] = 0;
+ en50221_app_mmi_menu_answ(stdcam->mmi_resource, stdcam->mmi_session_number,
+ atoi(ui_line));
+ mmi_state = MMI_STATE_OPEN;
+ break;
+ }
+ ui_linepos = 0;
+ } else {
+ if (ui_linepos < (sizeof(ui_line)-1)) {
+ ui_line[ui_linepos++] = c;
+ }
+ }
+}
+
+int gnutv_ca_new_pmt(struct mpeg_pmt_section *pmt)
+{
+ uint8_t capmt[4096];
+ int size;
+
+ if (stdcam == NULL)
+ return -1;
+
+ if (ca_resource_connected) {
+ fprintf(stderr, "Received new PMT - sending to CAM...\n");
+
+ // translate it into a CA PMT
+ int listmgmt = CA_LIST_MANAGEMENT_ONLY;
+ if (seenpmt) {
+ listmgmt = CA_LIST_MANAGEMENT_UPDATE;
+ }
+ seenpmt = 1;
+
+ if ((size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), moveca, listmgmt,
+ CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
+ fprintf(stderr, "Failed to format PMT\n");
+ return -1;
+ }
+
+ // set it
+ if (en50221_app_ca_pmt(stdcam->ca_resource, stdcam->ca_session_number, capmt, size)) {
+ fprintf(stderr, "Failed to send PMT\n");
+ return -1;
+ }
+
+ // we've seen this PMT
+ return 1;
+ }
+
+ return 0;
+}
+
+void gnutv_ca_new_dvbtime(time_t dvb_time)
+{
+ if (stdcam == NULL)
+ return;
+
+ if (stdcam->dvbtime)
+ stdcam->dvbtime(stdcam, dvb_time);
+}
+
+static void *camthread_func(void* arg)
+{
+ (void) arg;
+ int entered_menu = 0;
+
+ while(!camthread_shutdown) {
+ stdcam->poll(stdcam);
+
+ if ((!entered_menu) && cammenu && ca_resource_connected && stdcam->mmi_resource) {
+ en50221_app_ai_entermenu(stdcam->ai_resource, stdcam->ai_session_number);
+ entered_menu = 1;
+ }
+ }
+
+ return 0;
+}
+
+static int gnutv_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ fprintf(stderr, "CAM Application type: %02x\n", application_type);
+ fprintf(stderr, "CAM Application manufacturer: %04x\n", application_manufacturer);
+ fprintf(stderr, "CAM Manufacturer code: %04x\n", manufacturer_code);
+ fprintf(stderr, "CAM Menu string: %.*s\n", menu_string_length, menu_string);
+
+ return 0;
+}
+
+static int gnutv_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ fprintf(stderr, "CAM supports the following ca system ids:\n");
+ uint32_t i;
+ for(i=0; i< ca_id_count; i++) {
+ fprintf(stderr, " 0x%04x\n", ca_ids[i]);
+ }
+ ca_resource_connected = 1;
+ return 0;
+}
+
+static int gnutv_mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t delay)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+ (void) cmd_id;
+ (void) delay;
+
+ // note: not entirely correct as its supposed to delay if asked
+ mmi_state = MMI_STATE_CLOSED;
+ return 0;
+}
+
+static int gnutv_mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t mmi_mode)
+{
+ struct en50221_app_mmi_display_reply_details reply;
+ (void) arg;
+ (void) slot_id;
+
+ // don't support any commands but set mode
+ if (cmd_id != MMI_DISPLAY_CONTROL_CMD_ID_SET_MMI_MODE) {
+ en50221_app_mmi_display_reply(stdcam->mmi_resource, session_number,
+ MMI_DISPLAY_REPLY_ID_UNKNOWN_CMD_ID, &reply);
+ return 0;
+ }
+
+ // we only support high level mode
+ if (mmi_mode != MMI_MODE_HIGH_LEVEL) {
+ en50221_app_mmi_display_reply(stdcam->mmi_resource, session_number,
+ MMI_DISPLAY_REPLY_ID_UNKNOWN_MMI_MODE, &reply);
+ return 0;
+ }
+
+ // ack the high level open
+ reply.u.mode_ack.mmi_mode = mmi_mode;
+ en50221_app_mmi_display_reply(stdcam->mmi_resource, session_number,
+ MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK, &reply);
+ mmi_state = MMI_STATE_OPEN;
+ return 0;
+}
+
+static int gnutv_mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t blind_answer, uint8_t expected_answer_length,
+ uint8_t *text, uint32_t text_size)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ fprintf(stderr, "%.*s: ", text_size, text);
+ fflush(stdout);
+
+ mmi_enq_blind = blind_answer;
+ mmi_enq_length = expected_answer_length;
+ mmi_state = MMI_STATE_ENQ;
+ return 0;
+}
+
+static int gnutv_mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+ (void) item_raw_length;
+ (void) items_raw;
+
+ fprintf(stderr, "------------------------------\n");
+
+ if (title->text_length) {
+ fprintf(stderr, "%.*s\n", title->text_length, title->text);
+ }
+ if (sub_title->text_length) {
+ fprintf(stderr, "%.*s\n", sub_title->text_length, sub_title->text);
+ }
+
+ uint32_t i;
+ fprintf(stderr, "0. Quit menu\n");
+ for(i=0; i< item_count; i++) {
+ fprintf(stderr, "%i. %.*s\n", i+1, items[i].text_length, items[i].text);
+ }
+
+ if (bottom->text_length) {
+ fprintf(stderr, "%.*s\n", bottom->text_length, bottom->text);
+ }
+ fprintf(stderr, "Enter option: ");
+ fflush(stdout);
+
+ mmi_state = MMI_STATE_MENU;
+ return 0;
+}
diff --git a/util/gnutv/gnutv_ca.h b/util/gnutv/gnutv_ca.h
new file mode 100644
index 0000000..7b5d5b3
--- /dev/null
+++ b/util/gnutv/gnutv_ca.h
@@ -0,0 +1,40 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef gnutv_CA_H
+#define gnutv_CA_H 1
+
+struct gnutv_ca_params {
+ int adapter_id;
+ int caslot_num;
+ int cammenu;
+ int moveca;
+};
+
+extern void gnutv_ca_start(struct gnutv_ca_params *params);
+extern void gnutv_ca_ui(void);
+extern void gnutv_ca_stop(void);
+
+extern int gnutv_ca_new_pmt(struct mpeg_pmt_section *pmt);
+extern void gnutv_ca_new_dvbtime(time_t dvb_time);
+
+#endif
diff --git a/util/gnutv/gnutv_data.c b/util/gnutv/gnutv_data.c
new file mode 100644
index 0000000..7ac0f23
--- /dev/null
+++ b/util/gnutv/gnutv_data.c
@@ -0,0 +1,459 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+#define _LARGEFILE64_SOURCE 1
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libdvbapi/dvbaudio.h>
+#include <libucsi/mpeg/section.h>
+#include "gnutv.h"
+#include "gnutv_dvb.h"
+#include "gnutv_ca.h"
+#include "gnutv_data.h"
+
+static void *fileoutputthread_func(void* arg);
+static void *udpoutputthread_func(void* arg);
+
+static int gnutv_data_create_decoder_filter(int adapter, int demux, uint16_t pid, int pestype);
+static int gnutv_data_create_dvr_filter(int adapter, int demux, uint16_t pid);
+
+static void gnutv_data_decoder_pmt(struct mpeg_pmt_section *pmt);
+static void gnutv_data_dvr_pmt(struct mpeg_pmt_section *pmt);
+
+static void gnutv_data_append_pid_fd(int pid, int fd);
+static void gnutv_data_free_pid_fds(void);
+
+static pthread_t outputthread;
+static int outfd = -1;
+static int dvrfd = -1;
+static int pat_fd_dvrout = -1;
+static int pmt_fd_dvrout = -1;
+static int outputthread_shutdown = 0;
+
+static int usertp = 0;
+static int adapter_id = -1;
+static int demux_id = -1;
+static int output_type = 0;
+static struct addrinfo *outaddrs = NULL;
+
+struct pid_fd {
+ int pid;
+ int fd;
+};
+static struct pid_fd *pid_fds = NULL;
+static int pid_fds_count = 0;
+
+void gnutv_data_start(int _output_type,
+ int ffaudiofd, int _adapter_id, int _demux_id,
+ char *outfile,
+ char* outif, struct addrinfo *_outaddrs, int _usertp)
+{
+ usertp = _usertp;
+ demux_id = _demux_id;
+ adapter_id = _adapter_id;
+ output_type = _output_type;
+
+ // setup output
+ switch(output_type) {
+ case OUTPUT_TYPE_DECODER:
+ case OUTPUT_TYPE_DECODER_ABYPASS:
+ dvbaudio_set_bypass(ffaudiofd, (output_type == OUTPUT_TYPE_DECODER_ABYPASS) ? 1 : 0);
+ close(ffaudiofd);
+ break;
+
+ case OUTPUT_TYPE_STDOUT:
+ case OUTPUT_TYPE_FILE:
+ if (output_type == OUTPUT_TYPE_FILE) {
+ // open output file
+ outfd = open(outfile, O_WRONLY|O_CREAT|O_LARGEFILE|O_TRUNC, 0644);
+ if (outfd < 0) {
+ fprintf(stderr, "Failed to open output file\n");
+ exit(1);
+ }
+ } else {
+ outfd = STDOUT_FILENO;
+ }
+
+ // open dvr device
+ dvrfd = dvbdemux_open_dvr(adapter_id, 0, 1, 0);
+ if (dvrfd < 0) {
+ fprintf(stderr, "Failed to open DVR device\n");
+ exit(1);
+ }
+
+ pthread_create(&outputthread, NULL, fileoutputthread_func, NULL);
+ break;
+
+ case OUTPUT_TYPE_UDP:
+ outaddrs = _outaddrs;
+
+ // open output socket
+ outfd = socket(outaddrs->ai_family, outaddrs->ai_socktype, outaddrs->ai_protocol);
+ if (outfd < 0) {
+ fprintf(stderr, "Failed to open output socket\n");
+ exit(1);
+ }
+
+ // bind to local interface if requested
+ if (outif != NULL) {
+ if (setsockopt(outfd, SOL_SOCKET, SO_BINDTODEVICE, outif, strlen(outif)) < 0) {
+ fprintf(stderr, "Failed to bind to interface %s\n", outif);
+ exit(1);
+ }
+ }
+
+ // open dvr device
+ dvrfd = dvbdemux_open_dvr(adapter_id, 0, 1, 0);
+ if (dvrfd < 0) {
+ fprintf(stderr, "Failed to open DVR device\n");
+ exit(1);
+ }
+
+ pthread_create(&outputthread, NULL, udpoutputthread_func, NULL);
+ break;
+ }
+
+ // output PAT to DVR if requested
+ switch(output_type) {
+ case OUTPUT_TYPE_DVR:
+ case OUTPUT_TYPE_FILE:
+ case OUTPUT_TYPE_STDOUT:
+ case OUTPUT_TYPE_UDP:
+ pat_fd_dvrout = gnutv_data_create_dvr_filter(adapter_id, demux_id, TRANSPORT_PAT_PID);
+ }
+}
+
+void gnutv_data_stop()
+{
+ // shutdown output thread if necessary
+ if (dvrfd != -1) {
+ outputthread_shutdown = 1;
+ pthread_join(outputthread, NULL);
+ }
+ gnutv_data_free_pid_fds();
+ if (pat_fd_dvrout != -1)
+ close(pat_fd_dvrout);
+ if (pmt_fd_dvrout != -1)
+ close(pmt_fd_dvrout);
+ if (outaddrs)
+ freeaddrinfo(outaddrs);
+}
+
+void gnutv_data_new_pat(int pmt_pid)
+{
+ // output PMT to DVR if requested
+ switch(output_type) {
+ case OUTPUT_TYPE_DVR:
+ case OUTPUT_TYPE_FILE:
+ case OUTPUT_TYPE_STDOUT:
+ case OUTPUT_TYPE_UDP:
+ if (pmt_fd_dvrout != -1)
+ close(pmt_fd_dvrout);
+ pmt_fd_dvrout = gnutv_data_create_dvr_filter(adapter_id, demux_id, pmt_pid);
+ }
+}
+
+int gnutv_data_new_pmt(struct mpeg_pmt_section *pmt)
+{
+ // close all old PID FDs
+ gnutv_data_free_pid_fds();
+
+ // deal with the PMT appropriately
+ switch(output_type) {
+ case OUTPUT_TYPE_DECODER:
+ case OUTPUT_TYPE_DECODER_ABYPASS:
+ gnutv_data_decoder_pmt(pmt);
+ break;
+
+ case OUTPUT_TYPE_DVR:
+ case OUTPUT_TYPE_FILE:
+ case OUTPUT_TYPE_STDOUT:
+ case OUTPUT_TYPE_UDP:
+ gnutv_data_dvr_pmt(pmt);
+ break;
+ }
+
+ return 1;
+}
+
+static void *fileoutputthread_func(void* arg)
+{
+ (void)arg;
+ uint8_t buf[4096];
+ struct pollfd pollfd;
+ int written;
+
+ pollfd.fd = dvrfd;
+ pollfd.events = POLLIN|POLLPRI|POLLERR;
+
+ while(!outputthread_shutdown) {
+ if (poll(&pollfd, 1, 1000) != 1)
+ continue;
+ if (pollfd.revents & POLLERR) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "DVR device read failure\n");
+ return 0;
+ }
+
+ int size = read(dvrfd, buf, sizeof(buf));
+ if (size < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "DVR device read failure\n");
+ return 0;
+ }
+
+ written = 0;
+ while(written < size) {
+ int tmp = write(outfd, buf + written, size - written);
+ if (tmp == -1) {
+ if (errno != EINTR) {
+ fprintf(stderr, "Write error: %m\n");
+ break;
+ }
+ } else {
+ written += tmp;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#define TS_PAYLOAD_SIZE (188*7)
+
+static void *udpoutputthread_func(void* arg)
+{
+ (void)arg;
+ uint8_t buf[12 + TS_PAYLOAD_SIZE];
+ struct pollfd pollfd;
+ int bufsize = 0;
+ int bufbase = 0;
+ int readsize;
+ uint16_t rtpseq = 0;
+
+ pollfd.fd = dvrfd;
+ pollfd.events = POLLIN|POLLPRI|POLLERR;
+
+ if (usertp) {
+ srandom(time(NULL));
+ int ssrc = random();
+ rtpseq = random();
+ buf[0x0] = 0x80;
+ buf[0x1] = 0x21;
+ buf[0x4] = 0x00; // }
+ buf[0x5] = 0x00; // } FIXME: should really be a valid stamp
+ buf[0x6] = 0x00; // }
+ buf[0x7] = 0x00; // }
+ buf[0x8] = ssrc >> 24;
+ buf[0x9] = ssrc >> 16;
+ buf[0xa] = ssrc >> 8;
+ buf[0xb] = ssrc;
+ bufbase = 12;
+ }
+
+ while(!outputthread_shutdown) {
+ if (poll(&pollfd, 1, 1000) != 1)
+ continue;
+ if (pollfd.revents & POLLERR) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "DVR device read failure\n");
+ return 0;
+ }
+
+ readsize = TS_PAYLOAD_SIZE - bufsize;
+ readsize = read(dvrfd, buf + bufbase + bufsize, readsize);
+ if (readsize < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "DVR device read failure\n");
+ return 0;
+ }
+ bufsize += readsize;
+
+ if (bufsize == TS_PAYLOAD_SIZE) {
+ if (usertp) {
+ buf[2] = rtpseq >> 8;
+ buf[3] = rtpseq;
+ }
+ if (sendto(outfd, buf, bufbase + bufsize, 0, outaddrs->ai_addr, outaddrs->ai_addrlen) < 0) {
+ if (errno != EINTR) {
+ fprintf(stderr, "Socket send failure: %m\n");
+ return 0;
+ }
+ }
+ rtpseq++;
+ bufsize = 0;
+ }
+ }
+
+ if (bufsize) {
+ if (usertp) {
+ buf[2] = rtpseq >> 8;
+ buf[3] = rtpseq;
+ }
+ if (sendto(outfd, buf, bufbase + bufsize, 0, outaddrs->ai_addr, outaddrs->ai_addrlen) < 0) {
+ if (errno != EINTR)
+ fprintf(stderr, "Socket send failure: %m\n");
+ }
+ }
+
+ return 0;
+}
+
+static int gnutv_data_create_decoder_filter(int adapter, int demux, uint16_t pid, int pestype)
+{
+ int demux_fd = -1;
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ return -1;
+ }
+
+ // create a section filter
+ if (dvbdemux_set_pes_filter(demux_fd, pid, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DECODER, pestype, 1)) {
+ close(demux_fd);
+ return -1;
+ }
+
+ // done
+ return demux_fd;
+}
+
+static int gnutv_data_create_dvr_filter(int adapter, int demux, uint16_t pid)
+{
+ int demux_fd = -1;
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ return -1;
+ }
+
+ // create a section filter
+ if (dvbdemux_set_pid_filter(demux_fd, pid, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DVR, 1)) {
+ close(demux_fd);
+ return -1;
+ }
+
+ // done
+ return demux_fd;
+}
+
+static void gnutv_data_decoder_pmt(struct mpeg_pmt_section *pmt)
+{
+ int audio_pid = -1;
+ int video_pid = -1;
+ struct mpeg_pmt_stream *cur_stream;
+ mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
+ switch(cur_stream->stream_type) {
+ case 1:
+ case 2: // video
+ video_pid = cur_stream->pid;
+ break;
+
+ case 3:
+ case 4: // audio
+ audio_pid = cur_stream->pid;
+ break;
+ }
+ }
+
+ if (audio_pid != -1) {
+ int fd = gnutv_data_create_decoder_filter(adapter_id, demux_id, audio_pid, DVBDEMUX_PESTYPE_AUDIO);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to create dvr filter for PID %i\n", audio_pid);
+ } else {
+ gnutv_data_append_pid_fd(audio_pid, fd);
+ }
+ }
+ if (video_pid != -1) {
+ int fd = gnutv_data_create_decoder_filter(adapter_id, demux_id, video_pid, DVBDEMUX_PESTYPE_VIDEO);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to create dvr filter for PID %i\n", video_pid);
+ } else {
+ gnutv_data_append_pid_fd(video_pid, fd);
+ }
+ }
+ int fd = gnutv_data_create_decoder_filter(adapter_id, demux_id, pmt->pcr_pid, DVBDEMUX_PESTYPE_PCR);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to create dvr filter for PID %i\n", pmt->pcr_pid);
+ } else {
+ gnutv_data_append_pid_fd(pmt->pcr_pid, fd);
+ }
+}
+
+static void gnutv_data_dvr_pmt(struct mpeg_pmt_section *pmt)
+{
+ struct mpeg_pmt_stream *cur_stream;
+ mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
+ int fd = gnutv_data_create_dvr_filter(adapter_id, demux_id, cur_stream->pid);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to create dvr filter for PID %i\n", cur_stream->pid);
+ } else {
+ gnutv_data_append_pid_fd(cur_stream->pid, fd);
+ }
+ }
+}
+
+static void gnutv_data_append_pid_fd(int pid, int fd)
+{
+ struct pid_fd *tmp;
+ if ((tmp = realloc(pid_fds, (pid_fds_count +1) * sizeof(struct pid_fd))) == NULL) {
+ fprintf(stderr, "Out of memory when adding a new pid_fd\n");
+ exit(1);
+ }
+ tmp[pid_fds_count].pid = pid;
+ tmp[pid_fds_count].fd = fd;
+ pid_fds_count++;
+ pid_fds = tmp;
+}
+
+static void gnutv_data_free_pid_fds()
+{
+ if (pid_fds_count) {
+ int i;
+ for(i=0; i< pid_fds_count; i++) {
+ close(pid_fds[i].fd);
+ }
+ }
+ if (pid_fds)
+ free(pid_fds);
+
+ pid_fds_count = 0;
+ pid_fds = NULL;
+}
diff --git a/util/gnutv/gnutv_data.h b/util/gnutv/gnutv_data.h
new file mode 100644
index 0000000..8e47e3a
--- /dev/null
+++ b/util/gnutv/gnutv_data.h
@@ -0,0 +1,39 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef gnutv_DATA_H
+#define gnutv_DATA_H 1
+
+#include <netdb.h>
+
+extern void gnutv_data_start(int output_type,
+ int ffaudiofd, int adapter_id, int demux_id,
+ char *outfile,
+ char* outif, struct addrinfo *outaddrs, int usertp);
+extern void gnutv_data_stop(void);
+
+extern void gnutv_data_new_pat(int pmt_pid);
+extern int gnutv_data_new_pmt(struct mpeg_pmt_section *pmt);
+
+
+
+#endif
diff --git a/util/gnutv/gnutv_dvb.c b/util/gnutv/gnutv_dvb.c
new file mode 100644
index 0000000..a903c26
--- /dev/null
+++ b/util/gnutv/gnutv_dvb.c
@@ -0,0 +1,376 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <signal.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libucsi/section.h>
+#include <libucsi/mpeg/section.h>
+#include <libucsi/dvb/section.h>
+#include "gnutv.h"
+#include "gnutv_dvb.h"
+#include "gnutv_data.h"
+#include "gnutv_ca.h"
+
+#define FE_STATUS_PARAMS (DVBFE_INFO_LOCKSTATUS|DVBFE_INFO_SIGNAL_STRENGTH|DVBFE_INFO_BER|DVBFE_INFO_SNR|DVBFE_INFO_UNCORRECTED_BLOCKS)
+
+static int dvbthread_shutdown = 0;
+static pthread_t dvbthread;
+static int tune_state = 0;
+
+static int pat_version = -1;
+static int ca_pmt_version = -1;
+static int data_pmt_version = -1;
+
+static void *dvbthread_func(void* arg);
+
+static void process_pat(int pat_fd, struct gnutv_dvb_params *params, int *pmt_fd, struct pollfd *pollfd);
+static void process_tdt(int tdt_fd);
+static void process_pmt(int pmt_fd, struct gnutv_dvb_params *params);
+static int create_section_filter(int adapter, int demux, uint16_t pid, uint8_t table_id);
+
+
+int gnutv_dvb_start(struct gnutv_dvb_params *params)
+{
+ pthread_create(&dvbthread, NULL, dvbthread_func, (void*) params);
+ return 0;
+}
+
+void gnutv_dvb_stop(void)
+{
+ dvbthread_shutdown = 1;
+ pthread_join(dvbthread, NULL);
+}
+
+int gnutv_dvb_locked(void)
+{
+ return tune_state == 2;
+}
+
+static void *dvbthread_func(void* arg)
+{
+ int pat_fd = -1;
+ int pmt_fd = -1;
+ int tdt_fd = -1;
+ struct pollfd pollfds[3];
+
+ struct gnutv_dvb_params *params = (struct gnutv_dvb_params *) arg;
+
+ tune_state = 0;
+
+ // create PAT filter
+ if ((pat_fd = create_section_filter(params->adapter_id, params->demux_id,
+ TRANSPORT_PAT_PID, stag_mpeg_program_association)) < 0) {
+ fprintf(stderr, "Failed to create PAT section filter\n");
+ exit(1);
+ }
+ pollfds[0].fd = pat_fd;
+ pollfds[0].events = POLLIN|POLLPRI|POLLERR;
+
+ // create TDT filter
+ if ((tdt_fd = create_section_filter(params->adapter_id, params->demux_id, TRANSPORT_TDT_PID, stag_dvb_time_date)) < 0) {
+ fprintf(stderr, "Failed to create TDT section filter\n");
+ exit(1);
+ }
+ pollfds[1].fd = tdt_fd;
+ pollfds[1].events = POLLIN|POLLPRI|POLLERR;
+
+ // zero PMT filter
+ pollfds[2].fd = 0;
+ pollfds[2].events = 0;
+
+ // the DVB loop
+ while(!dvbthread_shutdown) {
+ // tune frontend + monitor lock status
+ if (tune_state == 0) {
+ // get the type of frontend
+ struct dvbfe_info result;
+ char *types;
+ memset(&result, 0, sizeof(result));
+ dvbfe_get_info(params->fe, 0, &result, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
+ switch(result.type) {
+ case DVBFE_TYPE_DVBS:
+ types = "DVB-S";
+ break;
+ case DVBFE_TYPE_DVBC:
+ types = "DVB-C";
+ break;
+ case DVBFE_TYPE_DVBT:
+ types = "DVB-T";
+ break;
+ case DVBFE_TYPE_ATSC:
+ types = "ATSC";
+ break;
+ default:
+ types = "Unknown";
+ }
+ fprintf(stderr, "Using frontend \"%s\", type %s\n", result.name, types);
+
+ // do we have a valid SEC configuration?
+ struct dvbsec_config *sec = NULL;
+ if (params->valid_sec)
+ sec = &params->sec;
+
+ // tune!
+ if (dvbsec_set(params->fe,
+ sec,
+ params->channel.polarization,
+ (params->channel.diseqc_switch & 0x01) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
+ (params->channel.diseqc_switch & 0x02) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
+ &params->channel.fe_params,
+ 0)) {
+ fprintf(stderr, "Failed to set frontend\n");
+ exit(1);
+ }
+
+ tune_state++;
+ } else if (tune_state == 1) {
+ struct dvbfe_info result;
+ memset(&result, 0, sizeof(result));
+ dvbfe_get_info(params->fe,
+ FE_STATUS_PARAMS,
+ &result,
+ DVBFE_INFO_QUERYTYPE_IMMEDIATE,
+ 0);
+
+ fprintf(stderr, "status %c%c%c%c%c | signal %04x | snr %04x | ber %08x | unc %08x | %s\r",
+ result.signal ? 'S' : ' ',
+ result.carrier ? 'C' : ' ',
+ result.viterbi ? 'V' : ' ',
+ result.sync ? 'Y' : ' ',
+ result.lock ? 'L' : ' ',
+ result.signal_strength,
+ result.snr,
+ result.ber,
+ result.ucblocks,
+ result.lock ? "FE_HAS_LOCK" : "");
+ fflush(stderr);
+
+ if (result.lock) {
+ tune_state++;
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ } else {
+ usleep(500000);
+ }
+ }
+
+ // is there SI data?
+ int count = poll(pollfds, 3, 100);
+ if (count < 0) {
+ if (errno != EINTR)
+ fprintf(stderr, "Poll error: %m\n");
+ break;
+ }
+ if (count == 0) {
+ continue;
+ }
+
+ // PAT
+ if (pollfds[0].revents & (POLLIN|POLLPRI)) {
+ process_pat(pat_fd, params, &pmt_fd, &pollfds[2]);
+ }
+
+ // TDT
+ if (pollfds[1].revents & (POLLIN|POLLPRI)) {
+ process_tdt(tdt_fd);
+ }
+
+ // PMT
+ if (pollfds[2].revents & (POLLIN|POLLPRI)) {
+ process_pmt(pmt_fd, params);
+ }
+ }
+
+ // close demuxers
+ if (pat_fd != -1)
+ close(pat_fd);
+ if (pmt_fd != -1)
+ close(pmt_fd);
+ if (tdt_fd != -1)
+ close(tdt_fd);
+
+ return 0;
+}
+
+static void process_pat(int pat_fd, struct gnutv_dvb_params *params, int *pmt_fd, struct pollfd *pollfd)
+{
+ int size;
+ uint8_t sibuf[4096];
+
+ // read the section
+ if ((size = read(pat_fd, sibuf, sizeof(sibuf))) < 0) {
+ return;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ return;
+ }
+
+ // parse section_ext
+ struct section_ext *section_ext = section_ext_decode(section, 0);
+ if (section_ext == NULL) {
+ return;
+ }
+ if (pat_version == section_ext->version_number) {
+ return;
+ }
+
+ // parse PAT
+ struct mpeg_pat_section *pat = mpeg_pat_section_codec(section_ext);
+ if (pat == NULL) {
+ return;
+ }
+
+ // try and find the requested program
+ struct mpeg_pat_program *cur_program;
+ mpeg_pat_section_programs_for_each(pat, cur_program) {
+ if (cur_program->program_number == params->channel.service_id) {
+ // close old PMT fd
+ if (*pmt_fd != -1)
+ close(*pmt_fd);
+
+ // create PMT filter
+ if ((*pmt_fd = create_section_filter(params->adapter_id, params->demux_id,
+ cur_program->pid, stag_mpeg_program_map)) < 0) {
+ return;
+ }
+ pollfd->fd = *pmt_fd;
+ pollfd->events = POLLIN|POLLPRI|POLLERR;
+
+ gnutv_data_new_pat(cur_program->pid);
+
+ // we have a new PMT pid
+ data_pmt_version = -1;
+ ca_pmt_version = -1;
+ break;
+ }
+ }
+
+ // remember the PAT version
+ pat_version = section_ext->version_number;
+}
+
+static void process_tdt(int tdt_fd)
+{
+ int size;
+ uint8_t sibuf[4096];
+
+ // read the section
+ if ((size = read(tdt_fd, sibuf, sizeof(sibuf))) < 0) {
+ return;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ return;
+ }
+
+ // parse TDT
+ struct dvb_tdt_section *tdt = dvb_tdt_section_codec(section);
+ if (tdt == NULL) {
+ return;
+ }
+
+ // done
+ gnutv_ca_new_dvbtime(dvbdate_to_unixtime(tdt->utc_time));
+}
+
+static void process_pmt(int pmt_fd, struct gnutv_dvb_params *params)
+{
+ int size;
+ uint8_t sibuf[4096];
+
+ // read the section
+ if ((size = read(pmt_fd, sibuf, sizeof(sibuf))) < 0) {
+ return;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ return;
+ }
+
+ // parse section_ext
+ struct section_ext *section_ext = section_ext_decode(section, 0);
+ if (section_ext == NULL) {
+ return;
+ }
+ if ((section_ext->table_id_ext != params->channel.service_id) ||
+ ((section_ext->version_number == data_pmt_version) &&
+ (section_ext->version_number == ca_pmt_version))) {
+ return;
+ }
+
+ // parse PMT
+ struct mpeg_pmt_section *pmt = mpeg_pmt_section_codec(section_ext);
+ if (pmt == NULL) {
+ return;
+ }
+
+ // do data handling
+ if (section_ext->version_number != data_pmt_version) {
+ if (gnutv_data_new_pmt(pmt) == 1)
+ data_pmt_version = pmt->head.version_number;
+ }
+
+ // do ca handling
+ if (section_ext->version_number != ca_pmt_version) {
+ if (gnutv_ca_new_pmt(pmt) == 1)
+ ca_pmt_version = pmt->head.version_number;
+ }
+}
+
+static int create_section_filter(int adapter, int demux, uint16_t pid, uint8_t table_id)
+{
+ int demux_fd = -1;
+ uint8_t filter[18];
+ uint8_t mask[18];
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ return -1;
+ }
+
+ // create a section filter
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = table_id;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(demux_fd, pid, filter, mask, 1, 1)) {
+ close(demux_fd);
+ return -1;
+ }
+
+ // done
+ return demux_fd;
+}
diff --git a/util/gnutv/gnutv_dvb.h b/util/gnutv/gnutv_dvb.h
new file mode 100644
index 0000000..83ec086
--- /dev/null
+++ b/util/gnutv/gnutv_dvb.h
@@ -0,0 +1,44 @@
+/*
+ gnutv utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef gnutv_DVB_H
+#define gnutv_DVB_H 1
+
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+#include <libdvbsec/dvbsec_api.h>
+
+struct gnutv_dvb_params {
+ int adapter_id;
+ int frontend_id;
+ int demux_id;
+ struct dvbcfg_zapchannel channel;
+ struct dvbsec_config sec;
+ int valid_sec;
+ int output_type;
+ struct dvbfe_handle *fe;
+};
+
+extern int gnutv_dvb_start(struct gnutv_dvb_params *params);
+extern void gnutv_dvb_stop(void);
+extern int gnutv_dvb_locked(void);
+
+#endif
diff --git a/util/lib/Makefile b/util/lib/Makefile
deleted file mode 100644
index 5f55636..0000000
--- a/util/lib/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-
-CC = gcc
-CFLAGS = -MD -g -Wall -O2 -I../../include -I.
-LFLAGS = -g -Wall
-
-OBJS = lnb.o
-SRCS = $(OBJS:.o=.c)
-
-TARGET = lnb.o
-
-$(TARGET): $(SRCS)
-
-.c.o:
- $(CC) $(CFLAGS) -c $< -o $@
-
-clean:
- $(RM) *.o *.d $(TARGET)
-
--include $(wildcard *.d) dummy
-
diff --git a/util/scan/Makefile b/util/scan/Makefile
index 4b29842..32d1f1c 100644
--- a/util/scan/Makefile
+++ b/util/scan/Makefile
@@ -1,21 +1,41 @@
+# Makefile for linuxtv.org dvb-apps/util/scan
-CC = gcc
-CFLAGS = -MD -g -Wall -O2 -I../../include
-LFLAGS = -g -Wall
+objects = atsc_psip_section.o \
+ diseqc.o \
+ dump-vdr.o \
+ dump-zap.o \
+ lnb.o \
+ scan.o \
+ section.o
-OBJS = diseqc.o dump-zap.o dump-vdr.o scan.o lnb.o section.o atsc_psip_section.o
-SRCS = $(OBJS:.o=.c)
+binaries = scan
-TARGET = scan
+inst_bin = $(binaries)
-$(TARGET): $(OBJS)
- $(CC) $(LFLAGS) -o $(TARGET) $(OBJS)
+removing = atsc_psip_section.c atsc_psip_section.h
-.c.o:
- $(CC) $(CFLAGS) -c $< -o $@
+CPPFLAGS += -DDATADIR=\"$(prefix)/share\"
-clean:
- $(RM) *.o *.d $(TARGET)
+.PHONY: all
--include $(wildcard *.d) dummy
+all: $(binaries)
+$(binaries): $(objects)
+
+$(objects): atsc_psip_section.c atsc_psip_section.h
+
+atsc_psip_section.c atsc_psip_section.h:
+ perl section_generate.pl atsc_psip_section.pl
+
+include ../../Make.rules
+
+install::
+ @echo installing scan files
+ @mkdir -p $(DESTDIR)$(sharedir)/dvb/atsc
+ @mkdir -p $(DESTDIR)$(sharedir)/dvb/dvb-c
+ @mkdir -p $(DESTDIR)$(sharedir)/dvb/dvb-s
+ @mkdir -p $(DESTDIR)$(sharedir)/dvb/dvb-t
+ @install -m 664 atsc/* $(DESTDIR)$(sharedir)/dvb/atsc/
+ @install -m 664 dvb-c/* $(DESTDIR)$(sharedir)/dvb/dvb-c/
+ @install -m 664 dvb-s/* $(DESTDIR)$(sharedir)/dvb/dvb-s/
+ @install -m 664 dvb-t/* $(DESTDIR)$(sharedir)/dvb/dvb-t/
diff --git a/util/scan/README b/util/scan/README
index a6c1767..1b3d13d 100644
--- a/util/scan/README
+++ b/util/scan/README
@@ -1,18 +1,20 @@
-Hi,
+This is a little channel scan utility to generate szap/tzap/czap/azap
+compatible channel lists. An atsc/dvbscan does not do a frequency scan, however,
+so you must manually provide the data for tuning to one or more start
+transponders. A number of initial-tuning-data files are provided for various
+dvb-c, dvb-s, dvb-t and atsc networks around the world. If you make a new one
+feel free to submit it to the linux-dvb mailing list
+http://www.linuxtv.org/lists.php.
-this is a little channel scan utility to generate szap/tzap/czap compatible
-channel lists. Scan does not do a frequency scan, however, so you must
-manually provide the data for tuning to one or more start transponders.
-A number of initial-tuning-data files are provided for various dvb-c, dvb-s
-and dvb-t networks around the world. If you make a new one feel free to
-submit it to the linux-dvb mailing list http://linuxtv.org/mailinglists.xml.
+Basic usage: ./dvbscan dvb-s/Astra-19.2E | tee mychannels.conf
+or ./atscscan atsc/us-NTSC-center-frequencies-8VSB
-Basic usage: ./scan dvb-s/Astra-19.2E | tee mychannels.conf
+If you want it to check a specific frequency, tune to that frequency
+(e.g. using szap/tzap/czap/azap) and then use './dvbscan -c' or './atscscan -c'.
-If you want it to check a specific frequency, tune to that frequency
-(e.g. using szap/tzap/czap) and then use './scan -c'.
+For more scan options see ./dvbscan -h or ./atscscan -h
-For more scan options see ./scan -h.
+atscscan is _just_ a copy of dvbscan to not confuse ATSC-user.
Good luck,
-Holger + Johannes
+Holger + Johannes + Patrick (beat me for ATSC)
diff --git a/util/scan/atsc/us-ATSC-center-frequencies-8VSB b/util/scan/atsc/us-ATSC-center-frequencies-8VSB
index ffd0b02..2e39de1 100644
--- a/util/scan/atsc/us-ATSC-center-frequencies-8VSB
+++ b/util/scan/atsc/us-ATSC-center-frequencies-8VSB
@@ -68,4 +68,3 @@ A 785028615 8VSB
A 791028615 8VSB
A 797028615 8VSB
A 803028615 8VSB
-
diff --git a/util/scan/atsc/us-NTSC-center-frequencies-8VSB b/util/scan/atsc/us-NTSC-center-frequencies-8VSB
index d21f9ae..6eb586c 100644
--- a/util/scan/atsc/us-NTSC-center-frequencies-8VSB
+++ b/util/scan/atsc/us-NTSC-center-frequencies-8VSB
@@ -68,4 +68,3 @@ A 785000000 8VSB
A 791000000 8VSB
A 797000000 8VSB
A 803000000 8VSB
-
diff --git a/util/scan/atsc/us-NY-TWC-NYC b/util/scan/atsc/us-NY-TWC-NYC
index 0ad6e48..932b377 100644
--- a/util/scan/atsc/us-NY-TWC-NYC
+++ b/util/scan/atsc/us-NY-TWC-NYC
@@ -1,53 +1,53 @@
-#initial tuning data for Time Warner Cable in New York City
-
-#80
-A 561000000 QAM256
-A 567000000 QAM256
-A 573000000 QAM256
-A 579000000 QAM256
-A 585000000 QAM256
-A 591000000 QAM256
-A 597000000 QAM256
-A 603000000 QAM256
-A 609000000 QAM256
-A 615000000 QAM256
-#90
-A 621000000 QAM256
-A 627000000 QAM256
-A 633000000 QAM256
-A 639000000 QAM256
-A 645000000 QAM256
-A 93000000 QAM256
-A 99000000 QAM256
-A 105000000 QAM256
-A 111025000 QAM256
-A 117025000 QAM256
-#100
-A 651000000 QAM256
-A 657000000 QAM256
-A 663000000 QAM256
-A 669000000 QAM256
-A 675000000 QAM256
-A 681000000 QAM256
-A 687000000 QAM256
-A 693000000 QAM256
-A 699000000 QAM256
-A 705000000 QAM256
-#110
-A 711000000 QAM256
-A 717000000 QAM256
-A 723000000 QAM256
-A 729000000 QAM256
-A 735000000 QAM256
-A 741000000 QAM256
-A 747000000 QAM256
-A 753000000 QAM256
-A 759000000 QAM256
-A 765000000 QAM256
-#120
-A 771000000 QAM256
-A 777000000 QAM256
-A 783000000 QAM256
-A 789000000 QAM256
-A 795000000 QAM256
-A 801000000 QAM256
+#initial tuning data for Time Warner Cable in New York City
+
+#80
+A 561000000 QAM256
+A 567000000 QAM256
+A 573000000 QAM256
+A 579000000 QAM256
+A 585000000 QAM256
+A 591000000 QAM256
+A 597000000 QAM256
+A 603000000 QAM256
+A 609000000 QAM256
+A 615000000 QAM256
+#90
+A 621000000 QAM256
+A 627000000 QAM256
+A 633000000 QAM256
+A 639000000 QAM256
+A 645000000 QAM256
+A 93000000 QAM256
+A 99000000 QAM256
+A 105000000 QAM256
+A 111025000 QAM256
+A 117025000 QAM256
+#100
+A 651000000 QAM256
+A 657000000 QAM256
+A 663000000 QAM256
+A 669000000 QAM256
+A 675000000 QAM256
+A 681000000 QAM256
+A 687000000 QAM256
+A 693000000 QAM256
+A 699000000 QAM256
+A 705000000 QAM256
+#110
+A 711000000 QAM256
+A 717000000 QAM256
+A 723000000 QAM256
+A 729000000 QAM256
+A 735000000 QAM256
+A 741000000 QAM256
+A 747000000 QAM256
+A 753000000 QAM256
+A 759000000 QAM256
+A 765000000 QAM256
+#120
+A 771000000 QAM256
+A 777000000 QAM256
+A 783000000 QAM256
+A 789000000 QAM256
+A 795000000 QAM256
+A 801000000 QAM256
diff --git a/util/scan/atsc_psip_section.c b/util/scan/atsc_psip_section.c
deleted file mode 100644
index 0c50014..0000000
--- a/util/scan/atsc_psip_section.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "atsc_psip_section.h"
-
-struct ATSC_extended_channel_name_descriptor read_ATSC_extended_channel_name_descriptor(const u8 *b)
-{
- struct ATSC_extended_channel_name_descriptor v;
- v.descriptor_tag = getBits(b, 0, 8);
- v.descriptor_length = getBits(b, 8, 8);
- v.TODO = getBits(b, 16, 1);
- return v;
-}
-
-struct ATSC_service_location_descriptor read_ATSC_service_location_descriptor(const u8 *b)
-{
- struct ATSC_service_location_descriptor v;
- v.descriptor_tag = getBits(b, 0, 8);
- v.descriptor_length = getBits(b, 8, 8);
- v.reserved = getBits(b, 16, 3);
- v.PCR_PID = getBits(b, 19,13);
- v.number_elements = getBits(b, 32, 8);
- return v;
-}
-
-struct ATSC_service_location_element read_ATSC_service_location_element(const u8 *b)
-{
- struct ATSC_service_location_element v;
- v.stream_type = getBits(b, 0, 8);
- v.reserved = getBits(b, 8, 3);
- v.elementary_PID = getBits(b, 11,13);
- v.ISO_639_language_code = getBits(b, 24,24);
- return v;
-}
-
-struct tvct_channel read_tvct_channel(const u8 *b)
-{
- struct tvct_channel v;
- v.short_name0 = getBits(b, 0,16);
- v.short_name1 = getBits(b, 16,16);
- v.short_name2 = getBits(b, 32,16);
- v.short_name3 = getBits(b, 48,16);
- v.short_name4 = getBits(b, 64,16);
- v.short_name5 = getBits(b, 80,16);
- v.short_name6 = getBits(b, 96,16);
- v.reserved0 = getBits(b,112, 4);
- v.major_channel_number = getBits(b,116,10);
- v.minor_channel_number = getBits(b,126,10);
- v.modulation_mode = getBits(b,136, 8);
- v.carrier_frequency = getBits(b,144,32);
- v.channel_TSID = getBits(b,176,16);
- v.program_number = getBits(b,192,16);
- v.ETM_location = getBits(b,208, 2);
- v.access_controlled = getBits(b,210, 1);
- v.hidden = getBits(b,211, 1);
- v.reserved1 = getBits(b,212, 2);
- v.hide_guide = getBits(b,214, 1);
- v.reserved2 = getBits(b,215, 3);
- v.service_type = getBits(b,218, 6);
- v.source_id = getBits(b,224,16);
- v.reserved3 = getBits(b,240, 6);
- v.descriptors_length = getBits(b,246,10);
- return v;
-}
-
diff --git a/util/scan/atsc_psip_section.h b/util/scan/atsc_psip_section.h
deleted file mode 100644
index c76bce7..0000000
--- a/util/scan/atsc_psip_section.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __ATSC_PSIP_SECTION_H_
-#define __ATSC_PSIP_SECTION_H_
-
-#include "section.h"
-
-#define ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR_ID 0xA0
-struct ATSC_extended_channel_name_descriptor {
- u8 descriptor_tag : 8;
- u8 descriptor_length : 8;
- u8 TODO : 1;
-} PACKED;
-struct ATSC_extended_channel_name_descriptor read_ATSC_extended_channel_name_descriptor(const u8 *);
-
-#define ATSC_SERVICE_LOCATION_DESCRIPTOR_ID 0xA1
-struct ATSC_service_location_descriptor {
- u8 descriptor_tag : 8;
- u8 descriptor_length : 8;
- u8 reserved : 3;
- u16 PCR_PID :13;
- u8 number_elements : 8;
-} PACKED;
-struct ATSC_service_location_descriptor read_ATSC_service_location_descriptor(const u8 *);
-
-struct ATSC_service_location_element {
- u8 stream_type : 8;
- u8 reserved : 3;
- u16 elementary_PID :13;
- u32 ISO_639_language_code :24;
-} PACKED;
-struct ATSC_service_location_element read_ATSC_service_location_element(const u8 *);
-
-struct tvct_channel {
- u16 short_name0 :16;
- u16 short_name1 :16;
- u16 short_name2 :16;
- u16 short_name3 :16;
- u16 short_name4 :16;
- u16 short_name5 :16;
- u16 short_name6 :16;
- u8 reserved0 : 4;
- u16 major_channel_number :10;
- u16 minor_channel_number :10;
- u8 modulation_mode : 8;
- u32 carrier_frequency :32;
- u16 channel_TSID :16;
- u16 program_number :16;
- u8 ETM_location : 2;
- u8 access_controlled : 1;
- u8 hidden : 1;
- u8 reserved1 : 2;
- u8 hide_guide : 1;
- u8 reserved2 : 3;
- u8 service_type : 6;
- u16 source_id :16;
- u8 reserved3 : 6;
- u16 descriptors_length :10;
-} PACKED;
-struct tvct_channel read_tvct_channel(const u8 *);
-
-#endif
diff --git a/util/scan/atsc_psip_section.pl b/util/scan/atsc_psip_section.pl
new file mode 100644
index 0000000..50548c6
--- /dev/null
+++ b/util/scan/atsc_psip_section.pl
@@ -0,0 +1,76 @@
+use strict;
+
+return {
+#{ 0x80, 0x80, "ATSC stuffing descriptor" },
+#{ 0x81, 0x81, "ATSC AC-3 audio descriptor" },
+#{ 0x82, 0x85, "ATSC TODO" },
+#{ 0x86, 0x86, "ATSC caption service descriptor" },
+#{ 0x87, 0x87, "ATSC content advisory descriptor" },
+#{ 0x88, 0x8F, "ATSC TODO" },
+#{ 0xA0, 0xA0, "ATSC extended channel name descriptor" },
+#{ 0xA1, 0xA1, "ATSC service location descriptor" },
+#{ 0xA2, 0xA2, "ATSC time-shifted service descriptor" },
+#{ 0xA3, 0xA3, "ATSC component name descriptor" },
+#{ 0xA4, 0xA7, "ATSC TODO" },
+#{ 0xA8, 0xA8, "ATSC DCC departing request descriptor" },
+#{ 0xA9, 0xA9, "ATSC DCC arriving request descriptor" },
+#{ 0xAA, 0xAA, "ATSC redistribution control descriptor" },
+ descriptors => [
+ { id => 0xa0,
+ name => "ATSC_extended_channel_name_descriptor",
+ elements => [
+ descriptor_tag => 8,
+ descriptor_length => 8,
+ TODO => 1,
+ ],
+ },
+ { id => 0xa1,
+ name => "ATSC_service_location_descriptor",
+ elements => [
+ descriptor_tag => 8,
+ descriptor_length => 8,
+ reserved => 3,
+ PCR_PID => 13,
+ number_elements => 8,
+ ],
+ }
+ ],
+ misc => [
+ { name => "ATSC_service_location_element",
+ elements => [
+ stream_type => 8,
+ reserved => 3,
+ elementary_PID => 13,
+ ISO_639_language_code => 24,
+ ],
+ },
+ { name => "tvct_channel",
+ elements => [
+ short_name0 => 16,
+ short_name1 => 16,
+ short_name2 => 16,
+ short_name3 => 16,
+ short_name4 => 16,
+ short_name5 => 16,
+ short_name6 => 16,
+ reserved0 => 4,
+ major_channel_number => 10,
+ minor_channel_number => 10,
+ modulation_mode => 8,
+ carrier_frequency => 32,
+ channel_TSID => 16,
+ program_number => 16,
+ ETM_location => 2,
+ access_controlled => 1,
+ hidden => 1,
+ reserved1 => 2,
+ hide_guide => 1,
+ reserved2 => 3,
+ service_type => 6,
+ source_id => 16,
+ reserved3 => 6,
+ descriptors_length => 10,
+ ],
+ },
+ ]
+};
diff --git a/util/scan/diseqc.c b/util/scan/diseqc.c
index a337e0a..c743fa5 100644
--- a/util/scan/diseqc.c
+++ b/util/scan/diseqc.c
@@ -37,9 +37,6 @@ void msleep(uint32_t msec)
;
}
-#define printf(x...)
-
-
int diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd **cmd,
fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
{
@@ -104,5 +101,3 @@ int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int hiband)
(i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF,
(i/4) % 2 ? SEC_MINI_B : SEC_MINI_A);
}
-
-
diff --git a/util/scan/diseqc.h b/util/scan/diseqc.h
index d44d99b..ad12e34 100644
--- a/util/scan/diseqc.h
+++ b/util/scan/diseqc.h
@@ -22,4 +22,3 @@ extern int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int fr
#endif
-
diff --git a/util/scan/dump-vdr.c b/util/scan/dump-vdr.c
index f030c93..ef4101e 100644
--- a/util/scan/dump-vdr.c
+++ b/util/scan/dump-vdr.c
@@ -138,7 +138,7 @@ void vdr_dump_service_parameter_set (FILE *f,
{
int i;
- if ((video_pid || audio_pid[0]) && ((ca_select > 0) || ((ca_select == 0) && (scrambled == 0)))) {
+ if (video_pid || audio_pid[0]) {
if (vdr_version <= 2) {
audio_lang = NULL;
network_id = 0;
@@ -174,10 +174,17 @@ void vdr_dump_service_parameter_set (FILE *f,
if (audio_lang && audio_lang[0][0])
fprintf (f, "=%.4s", audio_lang[0]);
}
- if (scrambled == 1) scrambled = ca_select;
+ if (scrambled == 1) {
+ if (ca_select == -1)
+ if (vdr_version <= 2)
+ scrambled = 1;
+ else
+ scrambled = 0;
+ else
+ scrambled = ca_select;
+ }
fprintf (f, ":%d:%d:%d:%d:%d:0", teletext_pid, scrambled,
service_id, network_id, transport_stream_id);
fprintf (f, "\n");
}
}
-
diff --git a/util/scan/dump-vdr.h b/util/scan/dump-vdr.h
index 13bd05a..f953b6e 100644
--- a/util/scan/dump-vdr.h
+++ b/util/scan/dump-vdr.h
@@ -36,4 +36,3 @@ void vdr_dump_service_parameter_set (FILE *f,
int channel_num);
#endif
-
diff --git a/util/scan/dump-zap.c b/util/scan/dump-zap.c
index 83505b9..3dcf71a 100644
--- a/util/scan/dump-zap.c
+++ b/util/scan/dump-zap.c
@@ -123,4 +123,3 @@ void zap_dump_service_parameter_set (FILE *f,
fprintf (f, ":%i:%i:%i", video_pid, audio_pid[0], service_id);
fprintf (f, "\n");
}
-
diff --git a/util/scan/dump-zap.h b/util/scan/dump-zap.h
index 6763dc2..e0aab6a 100644
--- a/util/scan/dump-zap.h
+++ b/util/scan/dump-zap.h
@@ -17,4 +17,3 @@ extern void zap_dump_service_parameter_set (FILE *f,
uint16_t service_id);
#endif
-
diff --git a/util/scan/dvb-c/at-Innsbruck b/util/scan/dvb-c/at-Innsbruck
new file mode 100644
index 0000000..ab920a3
--- /dev/null
+++ b/util/scan/dvb-c/at-Innsbruck
@@ -0,0 +1,8 @@
+# scan config for Innsbruck Telesystem cable provider
+# freq sr fec mod
+C 450000000 6875000 NONE QAM64
+C 490000000 6875000 NONE QAM64
+C 442000000 6875000 NONE QAM64
+C 546000000 6875000 NONE QAM64
+C 554000000 6875000 NONE QAM64
+C 562000000 6875000 NONE QAM64
diff --git a/util/scan/dvb-c/at-Liwest b/util/scan/dvb-c/at-Liwest
new file mode 100644
index 0000000..ad44f93
--- /dev/null
+++ b/util/scan/dvb-c/at-Liwest
@@ -0,0 +1,31 @@
+# Kabel Linz/AT Liwest
+# 2006-08-01
+# freq sr fec mod
+C 394000000 6900000 NONE QAM64
+C 402000000 6900000 NONE QAM64
+C 410000000 6875000 NONE QAM64
+C 418000000 6900000 NONE QAM64
+C 426000000 6900000 NONE QAM64
+C 434000000 6900000 NONE QAM64
+C 442000000 6900000 NONE QAM64
+C 506000000 6900000 NONE QAM64
+C 514000000 6900000 NONE QAM64
+C 522000000 6900000 NONE QAM64
+C 530000000 6900000 NONE QAM64
+C 538000000 6900000 NONE QAM64
+C 546000000 6900000 NONE QAM64
+C 554000000 6900000 NONE QAM64
+C 562000000 6900000 NONE QAM64
+C 570000000 6900000 NONE QAM64
+C 578000000 6900000 NONE QAM64
+C 586000000 6900000 NONE QAM64
+C 594000000 6900000 NONE QAM64
+C 666000000 6900000 NONE QAM64
+C 674000000 6900000 NONE QAM64
+C 682000000 6900000 NONE QAM64
+C 586000000 6900000 NONE QAM256
+C 634000000 6900000 NONE QAM256
+C 642000000 6900000 NONE QAM256
+C 650000000 6900000 NONE QAM256
+C 658000000 6900000 NONE QAM256
+C 690000000 6900000 NONE QAM256
diff --git a/util/scan/dvb-c/at-SalzburgAG b/util/scan/dvb-c/at-SalzburgAG
new file mode 100644
index 0000000..58fd3ce
--- /dev/null
+++ b/util/scan/dvb-c/at-SalzburgAG
@@ -0,0 +1,9 @@
+# scan config for Salzburg AG cable provider
+# freq sr fec mod
+C 306000000 6900000 NONE QAM64
+C 370000000 6900000 NONE QAM64
+C 410000000 6900000 NONE QAM64
+C 418000000 6900000 NONE QAM64
+C 426000000 6900000 NONE QAM64
+C 442000000 6900000 NONE QAM64
+C 306000000 6900000 NONE QAM64
diff --git a/util/scan/dvb-c/be-IN.DI-Integan b/util/scan/dvb-c/be-IN.DI-Integan
new file mode 100644
index 0000000..ca46717
--- /dev/null
+++ b/util/scan/dvb-c/be-IN.DI-Integan
@@ -0,0 +1,16 @@
+# Integan DVB-C (Belgium, IN.DI region)
+# freq sr fec mod
+C 330000000 6875000 NONE QAM256
+C 338000000 6875000 NONE QAM256
+C 346000000 6875000 NONE QAM256
+C 354000000 6875000 NONE QAM256
+C 362000000 6875000 NONE QAM64
+C 370000000 6875000 NONE QAM256
+C 378000000 6875000 NONE QAM256
+C 386000000 6875000 NONE QAM256
+C 394000000 6875000 NONE QAM256
+C 458000000 6875000 NONE QAM256
+C 466000000 6875000 NONE QAM256
+C 474000000 6875000 NONE QAM256
+C 482000000 6875000 NONE QAM256
+C 586000000 6875000 NONE QAM256
diff --git a/util/scan/dvb-c/ch-Video2000 b/util/scan/dvb-c/ch-Video2000
new file mode 100644
index 0000000..e3e47e5
--- /dev/null
+++ b/util/scan/dvb-c/ch-Video2000
@@ -0,0 +1,5 @@
+# Cable Video2000
+# Canton of Neuchatel, Switzerland
+
+# freq sr fec mod
+C 306000000 6900000 NONE QAM64
diff --git a/util/scan/dvb-c/ch-Zuerich-cablecom b/util/scan/dvb-c/ch-Zuerich-cablecom
new file mode 100644
index 0000000..41c2160
--- /dev/null
+++ b/util/scan/dvb-c/ch-Zuerich-cablecom
@@ -0,0 +1,3 @@
+# Kabel cablecom.ch Zuerich
+# freq sr fec mod
+C 410000000 6900000 NONE QAM64
diff --git a/util/scan/dvb-c/de-Berlin b/util/scan/dvb-c/de-Berlin
index 4a53b74..550ba76 100644
--- a/util/scan/dvb-c/de-Berlin
+++ b/util/scan/dvb-c/de-Berlin
@@ -2,3 +2,4 @@
# freq sr fec mod
C 394000000 6900000 NONE QAM64
C 113000000 6900000 NONE QAM64
+C 466000000 6900000 NONE QAM64
diff --git a/util/scan/dvb-c/de-Kabel_BW b/util/scan/dvb-c/de-Kabel_BW
new file mode 100644
index 0000000..437579f
--- /dev/null
+++ b/util/scan/dvb-c/de-Kabel_BW
@@ -0,0 +1,16 @@
+# Kabel-BW, Stand 04/2007
+#
+# Nur eine Anfangsfrequenz ist noetig, um den Ball ins
+# Rollen zu bringen. Quasi als Einstiegspunkt fuer eine
+# umfassende Suche. Es besteht kein Grund, sich um all die
+# vielen anderen Frequenzen und deren aktuell verwendete
+# Parameter zu kuemmern und diese dann womoeglich auch
+# noch auf einem aktuellen Stand halten zu wollen. Bei der
+# schieren Anzahl der innerhalb des Ausbaugebiets durch
+# Kabel BW genutzten Frequenzen waere das nur zeitraubend
+# und fehleranfaellig... ;-)
+#
+# Dirk Ritter <dirk@GNUmatic.de>
+#
+# freq sr fec mod
+C 113000000 6900000 NONE QAM64
diff --git a/util/scan/dvb-c/de-Muenchen b/util/scan/dvb-c/de-Muenchen
new file mode 100644
index 0000000..c963c88
--- /dev/null
+++ b/util/scan/dvb-c/de-Muenchen
@@ -0,0 +1,24 @@
+# 2008-04-28
+# Area: Muenchen City
+# Cable Provider: Kabel & Medien Service - http://www.atcable.de
+# Cable Content: Cablevista GmbH - http://www.cablevista.de
+#
+# freq sr fec mod
+C 113000000 6900000 AUTO QAM64
+C 121000000 6900000 AUTO QAM64
+C 346000000 6900000 AUTO QAM64
+C 354000000 6900000 AUTO QAM64
+C 362000000 6900000 AUTO QAM64
+C 370000000 6900000 AUTO QAM64
+C 378000000 6900000 AUTO QAM64
+C 386000000 6900000 AUTO QAM64
+C 394000000 6900000 AUTO QAM64
+C 402000000 6900000 AUTO QAM64
+C 410000000 6900000 AUTO QAM64
+C 418000000 6900000 AUTO QAM64
+C 426000000 6900000 AUTO QAM64
+C 434000000 6900000 AUTO QAM64
+C 442000000 6900000 AUTO QAM64
+C 450000000 6900000 AUTO QAM64
+C 466000000 6900000 AUTO QAM64
+C 458000000 6900000 AUTO QAM256
diff --git a/util/scan/dvb-c/de-Primacom b/util/scan/dvb-c/de-Primacom
new file mode 100644
index 0000000..3f93f75
--- /dev/null
+++ b/util/scan/dvb-c/de-Primacom
@@ -0,0 +1,29 @@
+# Primacom
+# freq sr fec mod
+C 306000000 6900000 AUTO QAM64
+C 314000000 6900000 AUTO QAM64
+C 322000000 6900000 AUTO QAM64
+C 330000000 6900000 AUTO QAM64
+C 338000000 6900000 AUTO QAM64
+C 346000000 6900000 AUTO QAM64
+C 354000000 6900000 AUTO QAM64
+C 362000000 6900000 AUTO QAM64
+C 370000000 6900000 AUTO QAM64
+C 378000000 6900000 AUTO QAM64
+C 386000000 6900000 AUTO QAM64
+C 394000000 6900000 AUTO QAM64
+C 402000000 6900000 AUTO QAM64
+C 410000000 6900000 AUTO QAM64
+C 418000000 6900000 AUTO QAM64
+C 426000000 6900000 AUTO QAM64
+C 434000000 6956000 AUTO QAM64
+C 610000000 6900000 AUTO QAM64
+C 746000000 6900000 AUTO QAM64
+C 754000000 6900000 AUTO QAM64
+C 762000000 6900000 AUTO QAM64
+C 802000000 6900000 AUTO QAM64
+C 810000000 6900000 AUTO QAM64
+C 818000000 6900000 AUTO QAM64
+C 826000000 6900000 AUTO QAM64
+C 834000000 6900000 AUTO QAM64
+C 634000000 6900000 AUTO QAM256
diff --git a/util/scan/dvb-c/de-Unitymedia b/util/scan/dvb-c/de-Unitymedia
new file mode 100644
index 0000000..96d1d38
--- /dev/null
+++ b/util/scan/dvb-c/de-Unitymedia
@@ -0,0 +1,35 @@
+# Unitymedia
+# Created from http://www.unitymedia.de/service/tv/frequenzen.html
+# and http://blob.unitymedia.de/Download/Unitymedia_Senderlineup_digital_2008-05-28.pdf
+# freq sr fec mod
+C 113000000 6900000 AUTO QAM256
+C 121000000 6900000 AUTO QAM256
+C 338000000 6900000 AUTO QAM256
+C 346000000 6900000 AUTO QAM256
+C 354000000 6900000 AUTO QAM64
+C 362000000 6900000 AUTO QAM64
+C 370000000 6900000 AUTO QAM64
+C 378000000 6900000 AUTO QAM64
+C 386000000 6900000 AUTO QAM64
+C 394000000 6900000 AUTO QAM256
+C 402000000 6900000 AUTO QAM256
+C 410000000 6900000 AUTO QAM256
+C 418000000 6900000 AUTO QAM256
+C 426000000 6900000 AUTO QAM256
+C 434000000 6900000 AUTO QAM256
+C 442000000 6900000 AUTO QAM64
+C 450000000 6900000 AUTO QAM64
+C 458000000 6900000 AUTO QAM256
+C 466000000 6900000 AUTO QAM256
+C 474000000 6900000 AUTO QAM64
+C 522000000 6900000 AUTO QAM256
+C 530000000 6900000 AUTO QAM256
+C 538000000 6900000 AUTO QAM256
+C 554000000 6900000 AUTO QAM256
+C 562000000 6900000 AUTO QAM256
+C 570000000 6900000 AUTO QAM256
+C 610000000 6900000 AUTO QAM64
+C 650000000 6900000 AUTO QAM256
+C 658000000 6900000 AUTO QAM256
+C 666000000 6900000 AUTO QAM256
+C 674000000 6900000 AUTO QAM256
diff --git a/util/scan/dvb-c/de-iesy b/util/scan/dvb-c/de-iesy
index a289951..6726bb7 100644
--- a/util/scan/dvb-c/de-iesy
+++ b/util/scan/dvb-c/de-iesy
@@ -1,3 +1,20 @@
-# Kabel iesy
+# Unity Media (iesy Hessen, ish Nordrhein-Westfalen)
# freq sr fec mod
+C 113000000 6900000 NONE QAM64
+C 121000000 6900000 NONE QAM64
+C 346000000 6900000 NONE QAM256
+C 354000000 6900000 NONE QAM64
+C 362000000 6900000 NONE QAM64
+C 370000000 6900000 NONE QAM64
+C 378000000 6900000 NONE QAM64
+C 386000000 6900000 NONE QAM64
+C 394000000 6900000 NONE QAM64
+C 402000000 6900000 NONE QAM256
C 410000000 6900000 NONE QAM64
+C 426000000 6900000 NONE QAM64
+C 434000000 6900000 NONE QAM256
+C 442000000 6900000 NONE QAM256
+C 450000000 6900000 NONE QAM64
+C 458000000 6900000 NONE QAM64
+C 466000000 6900000 NONE QAM64
+C 538000000 6900000 NONE QAM256
diff --git a/util/scan/dvb-c/de-neftv b/util/scan/dvb-c/de-neftv
new file mode 100644
index 0000000..59e7658
--- /dev/null
+++ b/util/scan/dvb-c/de-neftv
@@ -0,0 +1,23 @@
+# Cable conf for NEFtv
+# (Nuernberg, Erlangen, Fuerth and Herzogenaurach)
+
+# freq sr fec mod
+C 346000000 6875000 NONE QAM64
+C 354000000 6875000 NONE QAM64
+C 362000000 6875000 NONE QAM64
+C 370000000 6875000 NONE QAM64
+C 378000000 6875000 NONE QAM64
+C 386000000 6875000 NONE QAM64
+C 394000000 6875000 NONE QAM64
+C 402000000 6875000 NONE QAM64
+C 410000000 6875000 NONE QAM64
+C 418000000 6875000 NONE QAM64
+C 426000000 6875000 NONE QAM64
+C 434000000 6875000 NONE QAM64
+C 450000000 6875000 NONE QAM64
+C 458000000 6875000 NONE QAM64
+C 474000000 6875000 NONE QAM64
+C 490000000 6875000 NONE QAM64
+C 498000000 6875000 NONE QAM64
+C 514000000 6875000 NONE QAM64
+C 546000000 6875000 NONE QAM64
diff --git a/util/scan/dvb-c/dk-Odense b/util/scan/dvb-c/dk-Odense
new file mode 100644
index 0000000..132dd5a
--- /dev/null
+++ b/util/scan/dvb-c/dk-Odense
@@ -0,0 +1,10 @@
+# Glentevejs Antennelaug (Denmark / Odense)
+# freq sr fec mod
+C 442000000 6900000 NONE QAM64
+C 434000000 6875000 NONE QAM256
+C 255000000 5000000 2/3 QAM256
+C 506000000 6875000 2/3 QAM256
+C 562000000 6875000 2/3 QAM256
+C 610000000 6875000 2/3 QAM256
+C 754000000 6875000 2/3 QAM256
+C 770000000 6875000 2/3 QAM256
diff --git a/util/scan/dvb-c/es-Euskaltel b/util/scan/dvb-c/es-Euskaltel
new file mode 100644
index 0000000..7612425
--- /dev/null
+++ b/util/scan/dvb-c/es-Euskaltel
@@ -0,0 +1,19 @@
+# Scan config for Euskaltel (DVB-C)
+# Basque Country - Spain
+# file automatically generated by w_scan
+# (http://free.pages.at/wirbel4vdr/w_scan/index2.html)
+# freq sr fec mod
+C 714000000 6875000 3/4 QAM64
+C 722000000 6875000 3/4 QAM64
+C 730000000 6875000 3/4 QAM64
+C 738000000 6875000 3/4 QAM64
+C 746000000 6875000 3/4 QAM64
+C 754000000 6875000 3/4 QAM64
+C 762000000 6875000 3/4 QAM64
+C 770000000 6875000 3/4 QAM64
+C 778000000 6875000 3/4 QAM64
+C 786000000 6875000 3/4 QAM64
+C 794000000 6875000 3/4 QAM64
+C 802000000 6875000 3/4 QAM64
+C 810000000 6875000 3/4 QAM64
+C 818000000 6875000 3/4 QAM64
diff --git a/util/scan/dvb-c/fi-3ktv b/util/scan/dvb-c/fi-3ktv
index 55ccfd6..1ec2278 100644
--- a/util/scan/dvb-c/fi-3ktv
+++ b/util/scan/dvb-c/fi-3ktv
@@ -1,3 +1,20 @@
-# 3KTV
-# freq sr fec mod
-C 306000000 6875000 NONE QAM64
+# 3KTV network reference channels
+# freq sr fec mod
+C 154000000 6875000 NONE QAM128
+C 162000000 6875000 NONE QAM128
+C 170000000 6875000 NONE QAM128
+C 232000000 6875000 NONE QAM128
+C 298000000 6875000 NONE QAM128
+C 306000000 6875000 NONE QAM128
+C 314000000 6875000 NONE QAM128
+C 322000000 6875000 NONE QAM128
+C 330000000 6875000 NONE QAM128
+C 338000000 6875000 NONE QAM128
+C 346000000 6875000 NONE QAM128
+C 354000000 6875000 NONE QAM128
+C 362000000 6875000 NONE QAM128
+C 370000000 6875000 NONE QAM128
+C 378000000 6875000 NONE QAM128
+C 394000000 6875000 NONE QAM128
+C 402000000 6875000 NONE QAM128
+C 450000000 6875000 NONE QAM128
diff --git a/util/scan/dvb-c/fi-HTV b/util/scan/dvb-c/fi-HTV
new file mode 100644
index 0000000..ac00724
--- /dev/null
+++ b/util/scan/dvb-c/fi-HTV
@@ -0,0 +1,4 @@
+# HTV
+# freq sr fec mod
+C 283000000 5900000 NONE QAM128
+C 154000000 6900000 NONE QAM128
diff --git a/util/scan/dvb-c/fi-Joensuu-Tikka b/util/scan/dvb-c/fi-Joensuu-Tikka
new file mode 100644
index 0000000..d74462f
--- /dev/null
+++ b/util/scan/dvb-c/fi-Joensuu-Tikka
@@ -0,0 +1,13 @@
+# DVB-C, Tikka Media, Joensuu, Finland
+# freq sr fec mod
+C 154000000 6900000 NONE QAM128
+C 162000000 6900000 NONE QAM128
+C 170000000 6900000 NONE QAM128
+C 402000000 6900000 NONE QAM128
+C 410000000 6900000 NONE QAM128
+C 418000000 6900000 NONE QAM128
+C 426000000 6900000 NONE QAM128
+C 434000000 6900000 NONE QAM128
+C 458000000 6900000 NONE QAM128
+C 466000000 6900000 NONE QAM128
+C 474000000 6900000 NONE QAM128
diff --git a/util/scan/dvb-c/fi-TTV b/util/scan/dvb-c/fi-TTV
new file mode 100644
index 0000000..68cfbcd
--- /dev/null
+++ b/util/scan/dvb-c/fi-TTV
@@ -0,0 +1,4 @@
+# TTV
+# freq sr fec mod
+C 418000000 6900000 NONE QAM128
+C 346000000 6900000 NONE QAM128
diff --git a/util/scan/dvb-c/fi-Turku b/util/scan/dvb-c/fi-Turku
new file mode 100644
index 0000000..b6b435a
--- /dev/null
+++ b/util/scan/dvb-c/fi-Turku
@@ -0,0 +1,17 @@
+# Turun Kaapelitelevisio Oy (Turku)
+# freq sr fec mod
+C 146000000 6900000 NONE QAM128
+C 154000000 6900000 NONE QAM128
+C 162000000 6900000 NONE QAM128
+C 322000000 6900000 NONE QAM128
+C 330000000 6900000 NONE QAM128
+C 338000000 6900000 NONE QAM128
+C 362000000 6900000 NONE QAM128
+C 378000000 6900000 NONE QAM128
+C 386000000 6900000 NONE QAM128
+C 402000000 6900000 NONE QAM128
+C 410000000 6900000 NONE QAM128
+C 418000000 6900000 NONE QAM128
+C 426000000 6900000 NONE QAM128
+C 442000000 6900000 NONE QAM128
+C 354000000 6900000 NONE QAM256
diff --git a/util/scan/dvb-c/fi-jkl b/util/scan/dvb-c/fi-jkl
new file mode 100644
index 0000000..ad9811b
--- /dev/null
+++ b/util/scan/dvb-c/fi-jkl
@@ -0,0 +1,10 @@
+# OnCable (Finland / Jyväskylä)
+# freq sr fec mod
+C 514000000 6900000 NONE QAM128
+C 426000000 6900000 NONE QAM128
+C 162000000 6900000 NONE QAM128
+C 418000000 6900000 NONE QAM128
+C 490000000 6900000 NONE QAM128
+C 498000000 6900000 NONE QAM128
+C 402000000 6900000 NONE QAM128
+C 410000000 6900000 NONE QAM128
diff --git a/util/scan/dvb-c/fi-sonera b/util/scan/dvb-c/fi-sonera
new file mode 100644
index 0000000..54f3fe9
--- /dev/null
+++ b/util/scan/dvb-c/fi-sonera
@@ -0,0 +1,12 @@
+# Sonera kaapeli-tv (Finland)
+# Maksuttomat kanavat ovat 162 ja 170 MHz:n muxeissa
+#
+# freq      sr      fec  mod
+C 154000000 6900000 NONE QAM128
+C 162000000 6900000 NONE QAM128
+C 170000000 6900000 NONE QAM128
+C 314000000 6900000 NONE QAM128
+C 322000000 6900000 NONE QAM128
+C 338000000 6900000 NONE QAM128
+C 346000000 6900000 NONE QAM128
+C 354000000 6900000 NONE QAM128
diff --git a/util/scan/dvb-c/fr-noos-numericable b/util/scan/dvb-c/fr-noos-numericable
new file mode 100644
index 0000000..61e4b1e
--- /dev/null
+++ b/util/scan/dvb-c/fr-noos-numericable
@@ -0,0 +1,41 @@
+# Cable en France
+# freq sr fec mod
+C 123000000 6875000 NONE QAM64
+C 131000000 6875000 NONE QAM64
+C 139000000 6875000 NONE QAM64
+C 147000000 6875000 NONE QAM64
+C 155000000 6875000 NONE QAM64
+C 163000000 6875000 NONE QAM64
+C 171000000 6875000 NONE QAM64
+C 179000000 6875000 NONE QAM64
+C 187000000 6875000 NONE QAM64
+C 195000000 6875000 NONE QAM64
+C 203000000 6875000 NONE QAM64
+C 211000000 6875000 NONE QAM64
+C 219000000 6875000 NONE QAM64
+C 227000000 6875000 NONE QAM64
+C 235000000 6875000 NONE QAM64
+C 243000000 6875000 NONE QAM64
+C 251000000 6875000 NONE QAM64
+C 259000000 6875000 NONE QAM64
+C 267000000 6875000 NONE QAM64
+C 275000000 6875000 NONE QAM64
+C 283000000 6875000 NONE QAM64
+C 291000000 6875000 NONE QAM64
+C 299000000 6875000 NONE QAM64
+C 315000000 6875000 NONE QAM64
+C 323000000 6875000 NONE QAM64
+C 339000000 6875000 NONE QAM64
+C 347000000 6875000 NONE QAM64
+C 706000000 6875000 NONE QAM64
+C 714000000 6875000 NONE QAM64
+C 722000000 6875000 NONE QAM64
+C 730000000 6875000 NONE QAM64
+C 738000000 6875000 NONE QAM64
+C 746000000 6875000 NONE QAM64
+C 748000000 6875000 NONE QAM64
+C 754000000 6875000 NONE QAM64
+C 762000000 6875000 NONE QAM64
+C 834000000 6875000 NONE QAM64
+C 842000000 6875000 NONE QAM64
+C 850000000 6875000 NONE QAM64
diff --git a/util/scan/dvb-c/lu-Ettelbruck-ACE b/util/scan/dvb-c/lu-Ettelbruck-ACE
new file mode 100644
index 0000000..ba770c2
--- /dev/null
+++ b/util/scan/dvb-c/lu-Ettelbruck-ACE
@@ -0,0 +1,20 @@
+# Scan config for Antenne Collective Ettelbruck a.s.b.l.
+# (http://antenne-ettelbruck.lu)
+# Luxembourg - Ettelbruck
+# freq sr fec mod
+C 634000000 6900000 5/6 QAM64
+C 642000000 6900000 5/6 QAM64
+C 650000000 6900000 5/6 QAM64
+C 666000000 6900000 5/6 QAM64
+C 674000000 6900000 5/6 QAM64
+C 682000000 6900000 5/6 QAM64
+C 690000000 6900000 5/6 QAM64
+C 698000000 6900000 5/6 QAM64
+C 706000000 6900000 5/6 QAM64
+C 714000000 6900000 5/6 QAM64
+C 656000000 3450000 5/6 QAM64
+C 660000000 3450000 5/6 QAM64
+C 720000000 3450000 5/6 QAM64
+C 732000000 3450000 5/6 QAM64
+C 724000000 3450000 5/6 QAM64
+C 728000000 3450000 5/6 QAM64
diff --git a/util/scan/dvb-c/nl-Casema b/util/scan/dvb-c/nl-Casema
new file mode 100644
index 0000000..5c42d85
--- /dev/null
+++ b/util/scan/dvb-c/nl-Casema
@@ -0,0 +1,3 @@
+# Casema Netherlands
+# freq sr fec mod
+C 372000000 6875000 NONE QAM64
diff --git a/util/scan/dvb-c/no-Oslo-CanalDigital b/util/scan/dvb-c/no-Oslo-CanalDigital
new file mode 100644
index 0000000..96f454e
--- /dev/null
+++ b/util/scan/dvb-c/no-Oslo-CanalDigital
@@ -0,0 +1,13 @@
+# no-oslo-CanalDigital (cable)
+C 354000000 6950000 NONE QAM64
+C 362000000 6950000 NONE QAM64
+C 370000000 6950000 NONE QAM64
+C 378000000 6950000 NONE QAM64
+C 386000000 6950000 NONE QAM64
+C 394000000 6950000 NONE QAM64
+C 402000000 6950000 NONE QAM64
+C 410000000 6950000 NONE QAM64
+C 418000000 6950000 NONE QAM64
+C 426000000 6950000 NONE QAM64
+C 450000000 6950000 NONE QAM64
+C 474000000 6950000 NONE QAM64
diff --git a/util/scan/dvb-c/se-comhem b/util/scan/dvb-c/se-comhem
new file mode 100644
index 0000000..16bd7dd
--- /dev/null
+++ b/util/scan/dvb-c/se-comhem
@@ -0,0 +1,3 @@
+# com hem
+# freq sr fec mod
+C 362000000 6875000 NONE QAM64
diff --git a/util/scan/dvb-h/README b/util/scan/dvb-h/README
new file mode 100644
index 0000000..50e137d
--- /dev/null
+++ b/util/scan/dvb-h/README
@@ -0,0 +1,3 @@
+These files are mainly for informational and experimental purposes.
+The DVB-H file format hasn't been specified in any way; currently it's just
+a copy of the DVB-T format.
diff --git a/util/scan/dvb-h/fi-Helsinki b/util/scan/dvb-h/fi-Helsinki
new file mode 100644
index 0000000..c593929
--- /dev/null
+++ b/util/scan/dvb-h/fi-Helsinki
@@ -0,0 +1,2 @@
+# H freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+H 586000000 8MHz 1/2 NONE QAM16 8k 1/8 NONE
diff --git a/util/scan/dvb-h/fi-Oulu b/util/scan/dvb-h/fi-Oulu
new file mode 100644
index 0000000..7a6be88
--- /dev/null
+++ b/util/scan/dvb-h/fi-Oulu
@@ -0,0 +1,2 @@
+# H freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+H 498000000 8MHz 1/2 NONE QAM16 8k 1/8 NONE
diff --git a/util/scan/dvb-h/fi-Oulu-Nokia-devel b/util/scan/dvb-h/fi-Oulu-Nokia-devel
new file mode 100644
index 0000000..6213607
--- /dev/null
+++ b/util/scan/dvb-h/fi-Oulu-Nokia-devel
@@ -0,0 +1,4 @@
+# Nokia Oulu delelopment network
+# Network Name 'Nokia Oulu'
+# H freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+H 690000000 8MHz 1/2 NONE QPSK 8k 1/8 NONE
diff --git a/util/scan/dvb-h/fi-Turku b/util/scan/dvb-h/fi-Turku
new file mode 100644
index 0000000..7a6be88
--- /dev/null
+++ b/util/scan/dvb-h/fi-Turku
@@ -0,0 +1,2 @@
+# H freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+H 498000000 8MHz 1/2 NONE QAM16 8k 1/8 NONE
diff --git a/util/scan/dvb-s/ABS1-75.0E b/util/scan/dvb-s/ABS1-75.0E
new file mode 100644
index 0000000..26ea163
--- /dev/null
+++ b/util/scan/dvb-s/ABS1-75.0E
@@ -0,0 +1,10 @@
+# ABS-1 @ 75E
+# freq pol sr fec
+S 12518000 V 22000000 AUTO
+S 12548000 V 22000000 AUTO
+S 12579000 V 22000000 AUTO
+S 12640000 V 22000000 AUTO
+S 12670000 V 22000000 AUTO
+S 12693000 V 10000000 AUTO
+S 12704000 V 3900000 AUTO
+S 12740000 V 7408000 AUTO
diff --git a/util/scan/dvb-s/AMC1-103w b/util/scan/dvb-s/AMC1-103w
new file mode 100644
index 0000000..f09dc62
--- /dev/null
+++ b/util/scan/dvb-s/AMC1-103w
@@ -0,0 +1,5 @@
+# AMC 1 @ 103W
+# freq pol sr fec
+
+S 11942000 V 20000000 AUTO
+S 12100000 V 20000000 AUTO
diff --git a/util/scan/dvb-s/AMC2-85w b/util/scan/dvb-s/AMC2-85w
new file mode 100644
index 0000000..0cd0611
--- /dev/null
+++ b/util/scan/dvb-s/AMC2-85w
@@ -0,0 +1,6 @@
+# AMC 2 @ 85W
+# freq pol sr fec
+
+S 11731000 H 13021000 AUTO
+S 11744000 H 13021000 AUTO
+S 11771000 H 13021000 AUTO
diff --git a/util/scan/dvb-s/AMC3-87w b/util/scan/dvb-s/AMC3-87w
new file mode 100644
index 0000000..a081c57
--- /dev/null
+++ b/util/scan/dvb-s/AMC3-87w
@@ -0,0 +1,10 @@
+# AMC 3 @ 87.0W
+# freq pol sr fec
+
+S 11716000 H 04859000 AUTO
+S 12142000 V 30000000 AUTO
+S 12147000 H 04340000 AUTO
+S 12159000 H 04444000 AUTO
+S 12165000 H 04444000 AUTO
+S 12172000 H 04444000 AUTO
+S 12182000 V 30000000 AUTO
diff --git a/util/scan/dvb-s/AMC4-101w b/util/scan/dvb-s/AMC4-101w
new file mode 100644
index 0000000..dd732dd
--- /dev/null
+++ b/util/scan/dvb-s/AMC4-101w
@@ -0,0 +1,10 @@
+# AMC 4 @ 101.0W
+# freq pol sr fec
+
+S 11573000 V 07234000 AUTO
+S 11655000 V 30000000 AUTO
+S 11708000 V 02170000 AUTO
+S 11822000 H 05700000 AUTO
+S 11860000 H 28138000 AUTO
+S 12120000 V 30000000 AUTO
+S 12169000 H 03003000 AUTO
diff --git a/util/scan/dvb-s/AMC5-79w b/util/scan/dvb-s/AMC5-79w
new file mode 100644
index 0000000..0aeebc6
--- /dev/null
+++ b/util/scan/dvb-s/AMC5-79w
@@ -0,0 +1,5 @@
+# AMC 5 @ 79W
+# freq pol sr fec
+
+S 11742000 V 11110000 AUTO
+S 12182000 H 23000000 AUTO
diff --git a/util/scan/dvb-s/AMC6-72w b/util/scan/dvb-s/AMC6-72w
new file mode 100644
index 0000000..75307da
--- /dev/null
+++ b/util/scan/dvb-s/AMC6-72w
@@ -0,0 +1,44 @@
+# AMC 6 @ 72W
+# freq pol sr fec
+
+S 11482000 V 02656000 AUTO
+S 11494000 V 06560000 AUTO
+S 11499000 V 02964000 AUTO
+S 11505000 V 02963000 AUTO
+S 11546000 V 12000000 AUTO
+S 11548000 H 03002000 AUTO
+S 11552000 H 03002000 AUTO
+S 11557000 H 04392000 AUTO
+S 11563000 H 04392000 AUTO
+S 11570000 H 04392000 AUTO
+S 11576000 H 04392000 AUTO
+S 11586000 H 02652000 AUTO
+S 11603000 V 08500000 AUTO
+S 11605000 V 03600000 AUTO
+S 11611000 V 03400000 AUTO
+S 11628000 V 06560000 AUTO
+S 11637000 V 02800000 AUTO
+S 11641000 V 03702000 AUTO
+S 11648000 V 07500000 AUTO
+S 11667000 V 07400000 AUTO
+S 11674000 V 04000000 AUTO
+S 11680000 V 03255000 AUTO
+S 11703000 V 03979000 AUTO
+S 11709000 V 03979000 AUTO
+S 11715000 V 03979000 AUTO
+S 11746000 V 03979000 AUTO
+S 11748000 H 14015000 AUTO
+S 11752000 V 03979000 AUTO
+S 11763000 V 03979000 AUTO
+S 11817000 H 05000000 AUTO
+S 11874000 V 04000000 AUTO
+S 11986000 V 03979000 AUTO
+S 11995000 V 03979000 AUTO
+S 12004000 V 03979000 AUTO
+S 12013000 V 03979000 AUTO
+S 12025000 V 03979000 AUTO
+S 12031000 V 03979000 AUTO
+S 12046000 H 06111000 AUTO
+S 12055000 V 06890000 AUTO
+S 12144000 V 02573000 AUTO
+S 12188000 H 06511000 AUTO
diff --git a/util/scan/dvb-s/AMC9-83w b/util/scan/dvb-s/AMC9-83w
new file mode 100644
index 0000000..b7d0882
--- /dev/null
+++ b/util/scan/dvb-s/AMC9-83w
@@ -0,0 +1,18 @@
+# AMC 9 @ 83W
+# freq pol sr fec
+
+S 11745000 H 04232000 AUTO
+S 11751000 H 04232000 AUTO
+S 11757000 H 04232000 AUTO
+S 11763000 H 04232000 AUTO
+S 11769000 H 04232000 AUTO
+S 11775000 H 04232000 AUTO
+S 11826000 H 05632000 AUTO
+S 11864000 H 03979000 AUTO
+S 11871000 H 13000000 AUTO
+S 11889000 H 13025000 AUTO
+S 11926000 V 06511000 AUTO
+S 11953000 V 03979000 AUTO
+S 11960000 H 05000000 AUTO
+S 12002000 H 03979000 AUTO
+S 12011000 H 03979000 AUTO
diff --git a/util/scan/dvb-s/Amazonas-61.0W b/util/scan/dvb-s/Amazonas-61.0W
new file mode 100644
index 0000000..825b18a
--- /dev/null
+++ b/util/scan/dvb-s/Amazonas-61.0W
@@ -0,0 +1,54 @@
+# Amazonas @ 61.0W
+# freq pol sr fec
+
+S 3957000 H 06666000 AUTO
+S 3966000 H 06666000 AUTO
+S 3975000 H 06666000 AUTO
+S 3993000 H 06666000 AUTO
+S 4137000 H 03409000 AUTO
+S 3941000 V 03480000 AUTO
+S 12092000 V 30000000 AUTO
+S 12132000 V 30000000 AUTO
+S 4174000 H 03330000 AUTO
+S 11128000 V 06666000 AUTO
+S 11185000 V 11800000 AUTO
+S 11049000 V 02000000 AUTO
+S 12052000 V 27000000 AUTO
+S 10975000 V 27000000 AUTO
+S 3631000 H 02785000 AUTO
+S 10975000 H 26666000 AUTO
+S 3677000 H 04400000 AUTO
+S 3985000 H 04444000 AUTO
+S 11810000 V 06666000 AUTO
+S 11921000 V 21740000 AUTO
+S 11943000 V 04750000 AUTO
+S 4168000 H 07307000 AUTO
+S 12052000 H 26667000 AUTO
+S 12172000 H 27500000 AUTO
+S 12092000 H 27500000 AUTO
+S 11175000 H 28880000 AUTO
+S 4154000 H 09615000 AUTO
+S 11099000 V 07576000 AUTO
+S 11885000 H 04890000 AUTO
+S 11882000 V 11343000 AUTO
+S 11133000 V 03111000 AUTO
+S 11078000 V 01862000 AUTO
+S 11912000 H 02222000 AUTO
+S 11906000 H 02220000 AUTO
+S 11108000 V 02170000 AUTO
+S 12132000 H 27500000 AUTO
+S 11135000 H 26667000 AUTO
+S 4144000 V 04540000 AUTO
+S 11808000 H 11111000 AUTO
+S 11972000 H 26667000 AUTO
+S 4156000 V 04540000 AUTO
+S 4149000 V 04540000 AUTO
+S 3948000 H 13300000 AUTO
+S 4178000 H 03333000 AUTO
+S 11844000 V 16600000 AUTO
+S 11095000 H 30000000 AUTO
+S 11790000 H 03600000 AUTO
+S 12172000 V 30000000 AUTO
+S 11015000 H 26666000 AUTO
+S 11055000 H 27500000 AUTO
+S 12012000 H 27500000 AUTO
diff --git a/util/scan/dvb-s/Amos-4w b/util/scan/dvb-s/Amos-4w
new file mode 100644
index 0000000..3a80591
--- /dev/null
+++ b/util/scan/dvb-s/Amos-4w
@@ -0,0 +1,70 @@
+# Amos 6 @ 4W
+# freq pol sr fec
+
+S 11419000 H 2604000 AUTO
+S 11347000 H 2800000 AUTO
+S 11423000 H 2894000 AUTO
+S 11338000 H 2960000 AUTO
+S 11133000 H 2963000 AUTO
+S 11631000 H 3200000 AUTO
+S 11132000 V 3254000 AUTO
+S 11154000 V 3255000 AUTO
+S 11319000 H 3333000 AUTO
+S 11426000 H 3333000 AUTO
+S 11575000 H 3333000 AUTO
+S 11638000 H 3333000 AUTO
+S 11323000 H 3350000 AUTO
+S 11328000 H 3350000 AUTO
+S 11350000 H 3350000 AUTO
+S 11359000 H 3350000 AUTO
+S 11332000 H 3500000 AUTO
+S 11128000 V 3700000 AUTO
+S 11343000 H 3700000 AUTO
+S 11626000 H 4000000 AUTO
+S 11443000 H 4164000 AUTO
+S 11644000 V 4340000 AUTO
+S 11432000 V 4500000 AUTO
+S 10993000 H 4850000 AUTO
+S 11191000 H 6111000 AUTO
+S 11183000 H 6428000 AUTO
+S 10986000 H 6666000 AUTO
+S 11144000 H 6666000 AUTO
+S 11151000 H 6666000 AUTO
+S 11161000 H 6666000 AUTO
+S 11172000 H 6666000 AUTO
+S 11209000 H 6666000 AUTO
+S 11219000 H 6666000 AUTO
+S 11413000 H 6666000 AUTO
+S 11673000 H 6900000 AUTO
+S 11435000 H 7480000 AUTO
+S 11546000 H 8050000 AUTO
+S 11177000 V 8520000 AUTO
+S 11585000 H 8888000 AUTO
+S 11235000 H 10000000 AUTO
+S 11144000 V 11110000 AUTO
+S 11652000 V 11111000 AUTO
+S 11560000 H 13400000 AUTO
+S 11690000 H 15000000 AUTO
+S 11652000 H 16100000 AUTO
+S 11303000 H 19540000 AUTO
+S 11390000 H 24000000 AUTO
+S 10762000 H 26000000 AUTO
+S 10720000 V 27500000 AUTO
+S 10723000 H 27500000 AUTO
+S 10758000 V 27500000 AUTO
+S 10803000 V 27500000 AUTO
+S 10805000 H 27500000 AUTO
+S 10841000 V 27500000 AUTO
+S 10842000 H 27500000 AUTO
+S 10889000 H 27500000 AUTO
+S 10889000 V 27500000 AUTO
+S 10924000 H 27500000 AUTO
+S 10924000 V 27500000 AUTO
+S 10972000 V 27500000 AUTO
+S 11008000 V 27500000 AUTO
+S 11260000 H 27500000 AUTO
+S 11474000 V 27500000 AUTO
+S 11510000 V 27500000 AUTO
+S 11558000 V 27500000 AUTO
+S 11592000 V 27500000 AUTO
+S 11677000 V 27500000 AUTO
diff --git a/util/scan/dvb-s/Anik-F1-107.3W b/util/scan/dvb-s/Anik-F1-107.3W
new file mode 100644
index 0000000..2cf82aa
--- /dev/null
+++ b/util/scan/dvb-s/Anik-F1-107.3W
@@ -0,0 +1,7 @@
+# Anik F1 @ 107.3W
+# freq pol sr fec
+
+S 12002000 H 19980000 AUTO
+S 12063000 H 19980000 AUTO
+S 12155000 H 22500000 AUTO
+S 12185000 H 19980000 AUTO
diff --git a/util/scan/dvb-s/AsiaSat3S_C-105.5E b/util/scan/dvb-s/AsiaSat3S_C-105.5E
new file mode 100644
index 0000000..8e98a5d
--- /dev/null
+++ b/util/scan/dvb-s/AsiaSat3S_C-105.5E
@@ -0,0 +1,122 @@
+# AsiaSat 3S 105.5E C-BAND
+# Generated by Xingbo Wang
+# Apr 2, 2005
+
+# MPEG-2 QPSK
+# freq pol sr fec
+
+# [encrypted] ZEE English, ZEE TV International, ZEE Movies, MX, ZEE TV SE Asia, ZEE TV Asia, Trendz
+S 3700000 V 27500000 3/4
+
+# BTV World
+S 3725000 V 4450000 3/4
+
+# SAB TV
+S 3743000 V 3300000 3/4
+
+# AAJ TV
+S 3750000 V 2820000 3/4
+
+# Arirang TV
+S 3755150 V 4417900 7/8
+
+# [encrypted] STAR Plus India, STAR Movies India, STAR News India, National Geographic India, STAR Gold, STAR Movies (Middle East)
+# STAR Utsav
+S 3780000 V 28100000 3/4
+
+# Chinese Provincial TV: Guangxi, Shanxi, Anhui, Jiangsu, Heilongjiang
+S 3806000 V 4420000 3/4
+S 3813000 V 4420000 3/4
+S 3820000 V 4420000 3/4
+S 3827000 V 4420000 3/4
+S 3834000 V 4420000 3/4
+
+# [encrypted] ESPN Taiwan, STAR Sports Taiwan, ESPN Asia, STAR Sports South East Asia, STAR Sports India, ESPN India, ESPN Philippines
+S 3860000 V 27500000 3/4
+
+# Dragon TV
+S 3886000 V 4800000 3/4
+
+# Shandong TV
+S 3895000 V 6813000 3/4
+
+# CCTV-1(comprehensive), China National Radio Channel 1
+S 3904000 V 4420000 7/8
+
+# Jilin Provincial TV
+S 3914500 V 4420000 3/4
+
+# [encrypted] A1, History, STAR Movies SEA/China, STAR World India, STAR Plus Pakistan, Channel[V] India, STAR Chinese Movies, CNBC India, STAR One, STAR Vijay
+S 3980000 V 28100000 3/4
+
+# Sahara One, Sahara Samay National, Sahara Samay Mumbai, Sahara Samay Uttar Pradesh, Sahara Samay Bihar, Sahara Samay Madhya Pradesh
+S 4020000 V 27250000 3/4
+
+# Tianjin TV
+S 4046000 V 5950000 3/4
+
+# PTV-1, PTV World, PTV Channel 3, AVT Khyber
+S 4091000 V 13333000 3/4
+
+# PTV National
+S 4106000 V 3333300 3/4
+
+# Indus News
+S 4115750 V 3333000 3/4
+
+# [encrypted] ZEE Biz, ZEE News, ZEE Cinema, ZEE Music, Alpha TV Punjabi, Alpha TV Gujarati, Alpha TV Bangla, Alpha TV Marathi, Smile TV
+S 4140000 V 27500000 3/4
+
+# Chinese Provincial TV: Henan, Fujian, Jiangxi, Liaoning
+S 4166000 V 4420000 3/4
+S 4180000 V 4420000 3/4
+S 4187000 V 4420000 3/4
+S 4194000 V 4420000 3/4
+
+# CETV
+S 3680000 H 26670000 3/4
+
+# Channel NewsAsia
+S 3706000 H 6000000 3/4
+
+# Asia Plus
+S 3715500 H 7000000 3/4
+
+# TVB 8, CETV
+S 3729000 H 13650000 3/4
+
+# Network of the World, Bloomberg TV Asia, Indus Vision, Indus Music, Muslim TV Ahmadiyya, Living Asia Channel
+# [encrypted] Filmazia
+S 3760000 H 26000000 7/8
+
+# [encrypted] Fox News, Sky News, STAR Movies Int'l Taiwan, National Geographic Taiwan, STAR Chinese Channel, STAR Movies mandarin, Channel[V] Taiwan
+S 3840000 H 26850000 7/8
+
+# STAR Sports Asia
+# [encrypted] ESPN China, STAR Sports Hong Kong, ESPN Hong Kong
+S 3920000 H 26750000 7/8
+
+# [encrypted] CNN International Asia, CNN Newsource, Cartoon Network Asia, Cartoon Network Taiwan, Cartoon Network Philippines, Cartoon Network Australia/New Zealand, TCM Australia, Boomerang
+S 3960000 H 27500000 3/4
+
+# [encrypted] Phoenix Movies, star World Asia, Star Movies Int'l, Channel[V] International, National Geographic Regional
+# Phoenix Chinese Channel, Phoenix Info News Channel, Xiong Kong Int'l, Xing Kong Regional, Channel[V](Greater China)
+S 4000000 H 26850000 7/8
+
+# Chinese Provincial TV: Hubei, Sichuan
+S 4034600 H 4420000 3/4
+S 4051000 H 4420000 3/4
+
+# Chinese Provincial TV: Qinghai, Hunan
+S 4067000 H 4420000 3/4
+S 4082000 H 4420000 3/4
+
+# Sun TV
+S 4094000 H 5555000 3/4
+
+# MATV, Horizon Channel
+# [encrypted] Tian Ying Movies Channel, TVB Xing He Channel
+S 4111000 H 13650000 3/4
+
+# CCTV Channel 4 (International), Channel 9 (English language), CCTV E&F
+S 4129000 H 13240000 3/4
diff --git a/util/scan/dvb-s/Astra-28.2E b/util/scan/dvb-s/Astra-28.2E
new file mode 100644
index 0000000..908e428
--- /dev/null
+++ b/util/scan/dvb-s/Astra-28.2E
@@ -0,0 +1,186 @@
+# Astra 28.2E SDT info service transponder
+# freq pol sr fec
+
+## Astra 2A
+# Transponder 1
+S 11720000 H 29500000 3/4
+# Transponder 2
+S 11740000 V 27500000 2/3
+# Transponder 3
+S 11758000 H 27500000 2/3
+# Transponder 4
+S 11778000 V 27500000 2/3
+# Transponder 5
+S 11798000 H 29500000 3/4
+# Transponder 6
+S 11817000 V 27500000 2/3
+# Transponder 7
+S 11836000 H 27500000 2/3
+# Transponder 8
+S 11856000 V 27500000 2/3
+# Transponder 9
+S 11876000 H 27500000 2/3
+# Transponder 10
+S 11895000 V 27500000 2/3
+# Transponder 11
+S 11914000 H 27500000 2/3
+# Transponder 12
+S 11934000 V 27500000 2/3
+# Transponder 13
+S 11954000 H 27500000 2/3
+# Transponder 18
+S 12051000 V 27500000 2/3
+# Transponder 22
+S 12129000 V 27500000 2/3
+# Transponder 23
+S 12148000 H 27500000 2/3
+# Transponder 24
+S 12168000 V 27500000 2/3
+# Transponder 27
+S 12226000 H 27500000 2/3
+# Transponder 28
+S 12246000 V 27500000 2/3
+# Transponder 37
+S 12422000 H 27500000 2/3
+# Transponder 40
+S 12480000 V 27500000 2/3
+
+## Astra 2B
+# Transponder 14
+S 11973000 V 27500000 2/3
+# Transponder 15
+S 11992000 H 27500000 2/3
+# Transponder 16
+S 12012000 V 27500000 2/3
+# Transponder 17
+S 12032000 H 27500000 2/3
+# Transponder 19
+S 12070000 H 27500000 2/3
+# Transponder 20
+S 12090000 V 27500000 2/3
+# Transponder 21
+S 12110000 H 27500000 2/3
+# Transponder 25
+S 12188000 H 27500000 2/3
+# Transponder 26
+S 12207000 V 27500000 2/3
+# Transponder 29
+S 12266000 H 27500000 2/3
+# Transponder 30
+S 12285000 V 27500000 2/3
+# Transponder 31
+S 12304000 H 27500000 2/3
+# Transponder 32
+S 12324000 V 29500000 3/4
+# Transponder 33
+S 12344000 H 29500000 3/4
+# Transponder 34
+S 12363000 V 29500000 3/4
+# Transponder 35
+S 12382000 H 27500000 2/3
+# Transponder 36
+S 12402000 V 27500000 2/3
+# Transponder 38
+S 12441000 V 27500000 2/3
+# Transponder 39
+S 12460000 H 27500000 2/3
+
+## Astra 2D
+# Transponder 41
+S 10714000 H 22000000 5/6
+# Transponder 42
+S 10729000 V 22000000 5/6
+# Transponder 43
+S 10744000 H 22000000 5/6
+# Transponder 44
+S 10758000 V 22000000 5/6
+# Transponder 45
+S 10773000 H 22000000 5/6
+# Transponder 46
+S 10788000 V 22000000 5/6
+# Transponder 47
+S 10803000 H 22000000 5/6
+# Transponder 48
+S 10818000 V 22000000 5/6
+# Transponder 49
+S 10832000 H 22000000 5/6
+# Transponder 50
+S 10847000 V 22000000 5/6
+# Transponder 51
+S 10862000 H 22000000 5/6
+# Transponder 52
+S 10876000 V 22000000 5/6
+# Transponder 53
+S 10891000 H 22000000 5/6
+# Transponder 54
+S 10906000 V 22000000 5/6
+# Transponder 55
+S 10921000 H 22000000 5/6
+# Transponder 56
+S 10936000 V 22000000 5/6
+
+## Eurobird 1
+# Transponder C1
+S 11222170 H 27500000 2/3
+# Transponder C2
+S 11223670 V 27500000 2/3
+# Transponder C2
+S 11259000 V 27500000 2/3
+# Transponder C1
+S 11261000 H 27500000 2/3
+# Transponder C3
+S 11307000 H 27500000 2/3
+# Transponder C4
+S 11307000 V 27500000 2/3
+# Transponder C4
+S 11343000 V 27500000 2/3
+# Transponder C3
+S 11344000 H 27500000 2/3
+# Transponder C5
+S 11390000 H 27500000 2/3
+# Transponder C6
+S 11390000 V 27500000 2/3
+# Transponder C5
+S 11426000 H 27500000 2/3
+# Transponder C6
+S 11426000 V 27500000 2/3
+# Transponder D1
+S 11469000 H 27500000 2/3
+# Transponder D2S
+S 11488000 V 27500000 2/3
+# Transponder D3S
+S 11508000 H 27500000 2/3
+# Transponder D4S
+S 11527000 V 27500000 2/3
+# Transponder D5
+S 11546000 H 27500000 2/3
+# Transponder D6
+S 11565000 V 27500000 2/3
+# Transponder D7
+S 11585000 H 27500000 2/3
+# Transponder D8
+S 11603850 V 27500000 2/3
+# Transponder D9
+S 11623000 H 27500000 2/3
+# Transponder D10
+S 11642000 V 27500000 2/3
+# Transponder D11
+S 11661540 H 27500000 2/3
+# Transponder D12
+S 11680770 V 27500000 2/3
+# Transponder F1
+S 12524000 H 27500000 2/3
+# Transponder F2
+S 12524000 V 27500000 2/3
+# Transponder F1
+S 12560000 H 27500000 2/3
+# Transponder F2
+S 12560000 V 27500000 2/3
+# Transponder F4
+S 12596000 V 27500000 2/3
+# Transponder F3
+S 12607000 H 27500000 3/4
+# Transponder F4
+S 12629000 V 6111000 3/4
+# Transponder F5
+S 12692000 V 19532000 1/2
diff --git a/util/scan/dvb-s/Atlantic-Bird-1-12.5W b/util/scan/dvb-s/Atlantic-Bird-1-12.5W
new file mode 100644
index 0000000..5c38433
--- /dev/null
+++ b/util/scan/dvb-s/Atlantic-Bird-1-12.5W
@@ -0,0 +1,20 @@
+# Atlantic Bird 1 @ 12.5W
+# freq pol sr fec
+
+S 11682000 H 05632000 AUTO
+S 11673000 H 06111000 AUTO
+S 11664000 H 06111000 AUTO
+S 11655000 H 06666000 AUTO
+S 11690000 H 05700000 AUTO
+S 11596000 V 27500000 AUTO
+S 11618000 H 02324000 AUTO
+S 11590000 H 06111000 AUTO
+S 11597000 H 03184000 AUTO
+S 11629000 H 06507000 AUTO
+S 11622000 H 03255000 AUTO
+S 11585000 H 05632000 AUTO
+S 11643000 H 02398000 AUTO
+S 11647000 H 03990000 AUTO
+S 11647000 V 03990000 AUTO
+S 11693000 V 04800000 AUTO
+S 11644000 V 04800000 AUTO
diff --git a/util/scan/dvb-s/BrasilSat-B1-75.0W b/util/scan/dvb-s/BrasilSat-B1-75.0W
new file mode 100644
index 0000000..9349d93
--- /dev/null
+++ b/util/scan/dvb-s/BrasilSat-B1-75.0W
@@ -0,0 +1,11 @@
+# Brasilsat B1 @ 75.0W
+# freq pol sr fec
+
+S 3648000 V 04285000 AUTO
+S 3657000 V 06620000 AUTO
+S 3653000 V 04710000 AUTO
+S 3655000 H 06620000 AUTO
+S 3629000 H 06620000 AUTO
+S 3711000 H 03200000 AUTO
+S 3644000 V 04440000 AUTO
+S 3638000 H 04440000 AUTO
diff --git a/util/scan/dvb-s/BrasilSat-B2-65.0W b/util/scan/dvb-s/BrasilSat-B2-65.0W
new file mode 100644
index 0000000..383c223
--- /dev/null
+++ b/util/scan/dvb-s/BrasilSat-B2-65.0W
@@ -0,0 +1,34 @@
+# Brasilsat B2 @ 65.0W
+# freq pol sr fec
+
+S 3745000 H 03540000 AUTO
+S 4008000 H 03333000 AUTO
+S 4011000 V 05000000 AUTO
+S 3792000 V 03393000 AUTO
+S 4104000 V 03214000 AUTO
+S 4097000 V 06667000 AUTO
+S 3905000 H 06666000 AUTO
+S 3935000 H 06666000 AUTO
+S 3890000 H 06666000 AUTO
+S 3925000 H 06666000 AUTO
+S 4112000 V 04285000 AUTO
+S 3650000 V 04440000 AUTO
+S 3736000 H 01808000 AUTO
+S 3787000 H 06666000 AUTO
+S 3876000 V 02740000 AUTO
+S 4117000 V 02963000 AUTO
+S 3815000 H 06666000 AUTO
+S 3793000 H 06666000 AUTO
+S 3721000 H 02963000 AUTO
+S 3684000 H 06666000 AUTO
+S 3915000 H 06666000 AUTO
+S 3766000 H 03336000 AUTO
+S 3847000 H 04444000 AUTO
+S 3706000 H 02462000 AUTO
+S 3667000 H 07236000 AUTO
+S 3771000 V 01480000 AUTO
+S 3734000 V 02852000 AUTO
+S 3810000 H 13333000 AUTO
+S 3762000 H 02222000 AUTO
+S 3834000 H 03572000 AUTO
+S 3850000 H 01570000 AUTO
diff --git a/util/scan/dvb-s/BrasilSat-B3-84.0W b/util/scan/dvb-s/BrasilSat-B3-84.0W
new file mode 100644
index 0000000..5ad005e
--- /dev/null
+++ b/util/scan/dvb-s/BrasilSat-B3-84.0W
@@ -0,0 +1,85 @@
+# Brasilsat B3 @ 84.0W
+# freq pol sr fec
+
+S 3728000 H 04340000 AUTO
+S 3698000 V 03333000 AUTO
+S 4054000 V 01287000 AUTO
+S 3745000 H 04300000 AUTO
+S 3738000 V 04708000 AUTO
+S 3923000 V 01808000 AUTO
+S 3768000 V 08000000 AUTO
+S 3955000 V 04340000 AUTO
+S 4167000 H 03255000 AUTO
+S 3791000 V 03330000 AUTO
+S 3866000 H 04425000 AUTO
+S 3932000 V 03255000 AUTO
+S 4132000 V 02532000 AUTO
+S 3906000 H 03928000 AUTO
+S 3858000 V 04288000 AUTO
+S 3665000 V 03177000 AUTO
+S 3732000 V 03214000 AUTO
+S 3774000 H 03330000 AUTO
+S 3927000 V 03255000 AUTO
+S 3710000 H 03261000 AUTO
+S 3883000 H 04278000 AUTO
+S 3770000 H 03333000 AUTO
+S 3754000 V 05000000 AUTO
+S 3764000 H 04285000 AUTO
+S 3910000 H 03616000 AUTO
+S 3705000 H 04280000 AUTO
+S 3852000 V 03806000 AUTO
+S 3845000 H 10127000 AUTO
+S 3936000 V 03255000 AUTO
+S 3653000 V 03807000 AUTO
+S 3751000 H 03565000 AUTO
+S 3871000 H 04435000 AUTO
+S 3895000 H 04430000 AUTO
+S 3936000 H 03255000 AUTO
+S 3800000 H 03255000 AUTO
+S 3855000 H 04000000 AUTO
+S 4171000 H 02170000 AUTO
+S 3716000 H 04800000 AUTO
+S 4068000 H 02600000 AUTO
+S 4070000 V 02964000 AUTO
+S 3949000 V 04340000 AUTO
+S 3684000 V 03200000 AUTO
+S 4169000 V 08140000 AUTO
+S 4144000 H 02734000 AUTO
+S 3736000 H 04285000 AUTO
+S 3790000 H 10444000 AUTO
+S 3724000 V 02075000 AUTO
+S 4121000 H 02500000 AUTO
+S 3629000 H 06666000 AUTO
+S 3970000 V 04445000 AUTO
+S 3985000 V 03300000 AUTO
+S 3916000 H 03255000 AUTO
+S 4155000 V 03255000 AUTO
+S 3692000 V 03330000 AUTO
+S 3644000 V 04687000 AUTO
+S 4087000 H 17200000 AUTO
+S 3889000 H 04440000 AUTO
+S 4176000 V 03515000 AUTO
+S 3829000 V 04340000 AUTO
+S 3805000 V 02662000 AUTO
+S 3943000 V 02460000 AUTO
+S 3757000 H 03565000 AUTO
+S 3696000 H 01808000 AUTO
+S 3989000 V 02666000 AUTO
+S 3690000 V 03200000 AUTO
+S 3657000 V 03600000 AUTO
+S 3996000 V 02300000 AUTO
+S 3926000 H 04000000 AUTO
+S 4126000 H 04000000 AUTO
+S 4136000 H 02142000 AUTO
+S 3675000 V 04285000 AUTO
+S 3931000 H 04000000 AUTO
+S 3786000 V 04286000 AUTO
+S 3688000 V 02308000 AUTO
+S 4075000 V 04444000 AUTO
+S 3911000 V 03255000 AUTO
+S 3824000 H 03002000 AUTO
+S 3778000 V 06850000 AUTO
+S 3710000 V 12960000 AUTO
+S 3877000 H 04450000 AUTO
+S 3940000 V 03255000 AUTO
+S 4064000 H 03300000 AUTO
diff --git a/util/scan/dvb-s/BrasilSat-B4-70.0W b/util/scan/dvb-s/BrasilSat-B4-70.0W
new file mode 100644
index 0000000..9ff8c1b
--- /dev/null
+++ b/util/scan/dvb-s/BrasilSat-B4-70.0W
@@ -0,0 +1,39 @@
+# Brasilsat B4 @ 70.0W
+# freq pol sr fec
+
+S 3951000 H 03214000 AUTO
+S 3714000 V 04400000 AUTO
+S 3672000 H 04713000 AUTO
+S 3955000 H 04400000 AUTO
+S 3965000 V 02930000 AUTO
+S 3628000 H 03000000 AUTO
+S 3644000 V 03214000 AUTO
+S 3650000 H 04285000 AUTO
+S 3688000 H 06000000 AUTO
+S 3680000 H 06000000 AUTO
+S 3662000 V 04606000 AUTO
+S 3945000 H 03214000 AUTO
+S 3640000 H 03263000 AUTO
+S 3979000 V 03617000 AUTO
+S 3752000 V 06220000 AUTO
+S 3685000 V 04500000 AUTO
+S 3650000 V 04400000 AUTO
+S 3985000 H 02170000 AUTO
+S 4010000 H 13021000 AUTO
+S 3665000 H 04700000 AUTO
+S 3637000 H 02228000 AUTO
+S 3708000 V 03928000 AUTO
+S 4047000 V 07143000 AUTO
+S 3672000 V 08454000 AUTO
+S 3820000 V 27500000 AUTO
+S 3940000 V 27500000 AUTO
+S 3964000 H 01875000 AUTO
+S 3695000 H 03598000 AUTO
+S 3900000 V 27500000 AUTO
+S 3645000 H 03520000 AUTO
+S 3983000 V 01630000 AUTO
+S 3631000 H 04687000 AUTO
+S 3874000 V 05926000 AUTO
+S 3700000 V 09123000 AUTO
+S 3997000 V 02300000 AUTO
+S 3973000 V 04338000 AUTO
diff --git a/util/scan/dvb-s/Estrela-do-Sul-63.0W b/util/scan/dvb-s/Estrela-do-Sul-63.0W
new file mode 100644
index 0000000..fc3cfa0
--- /dev/null
+++ b/util/scan/dvb-s/Estrela-do-Sul-63.0W
@@ -0,0 +1,27 @@
+# Estrela do Sul @ 63.0W
+# freq pol sr fec
+
+S 11892000 V 02964000 AUTO
+S 11987000 H 03330000 AUTO
+S 12054000 H 26660000 AUTO
+S 11830000 V 06000000 AUTO
+S 11603000 V 03124000 AUTO
+S 11598000 V 03124000 AUTO
+S 11803000 V 04444000 AUTO
+S 11958000 H 04444000 AUTO
+S 11610000 V 03124000 AUTO
+S 11861000 V 02964000 AUTO
+S 11879000 V 02964000 AUTO
+S 11903000 V 02362000 AUTO
+S 11817000 V 06666000 AUTO
+S 11577000 V 03124000 AUTO
+S 11582000 V 03124000 AUTO
+S 11982000 H 08888000 AUTO
+S 11888000 V 02392000 AUTO
+S 11898000 V 02480000 AUTO
+S 11871000 V 02000000 AUTO
+S 11795000 V 04444000 AUTO
+S 11845000 V 04444000 AUTO
+S 11640000 V 18100000 AUTO
+S 11875000 V 03333000 AUTO
+S 11543000 V 10410000 AUTO
diff --git a/util/scan/dvb-s/Eurobird1-28.5E b/util/scan/dvb-s/Eurobird1-28.5E
new file mode 100644
index 0000000..5fd4a90
--- /dev/null
+++ b/util/scan/dvb-s/Eurobird1-28.5E
@@ -0,0 +1,5 @@
+# Eurobird 28.5E SDT info service transponder
+# freq pol sr fec
+S 11623000 H 27500000 2/3
+S 11224000 V 27500000 2/3
+S 11527000 V 27500000 2/3
diff --git a/util/scan/dvb-s/EutelsatW2-16E b/util/scan/dvb-s/EutelsatW2-16E
new file mode 100644
index 0000000..40023a8
--- /dev/null
+++ b/util/scan/dvb-s/EutelsatW2-16E
@@ -0,0 +1,59 @@
+# Eutelsat W2 @ 16E
+# freq pol sr fec
+
+S 10957000 H 2821000 AUTO
+S 10968000 H 6400000 AUTO
+S 10972000 V 27500000 AUTO
+S 10976000 H 6400000 AUTO
+S 10989000 H 6400000 AUTO
+S 10997000 H 6400000 AUTO
+S 11005000 H 6400000 AUTO
+S 11011000 V 27500000 AUTO
+S 11015000 H 6400000 AUTO
+S 11025000 H 2894000 AUTO
+S 11046000 H 10555000 AUTO
+S 11057000 H 3327000 AUTO
+S 11061000 H 5722000 AUTO
+S 11078000 H 5208000 AUTO
+S 11092000 V 32000000 AUTO
+S 11094000 H 2734000 AUTO
+S 11132000 V 14185000 AUTO
+S 11178000 V 27500000 AUTO
+S 11192000 H 2667000 AUTO
+S 11267000 H 2170000 AUTO
+S 11276000 H 11100000 AUTO
+S 11294000 H 13333000 AUTO
+S 11304000 V 30000000 AUTO
+S 11324000 H 27500000 AUTO
+S 11428000 V 30000000 AUTO
+S 11449000 H 27500000 AUTO
+S 11471000 V 29950000 AUTO
+S 11492000 H 29950000 AUTO
+S 11513000 V 29950000 AUTO
+S 11534000 H 30000000 AUTO
+S 11554000 V 30000000 AUTO
+S 11575000 H 30000000 AUTO
+S 11594000 V 28800000 AUTO
+S 11617000 H 29950000 AUTO
+S 11634000 V 17578000 AUTO
+S 11658000 H 30000000 AUTO
+S 11659000 V 17578000 AUTO
+S 11682000 V 14468000 AUTO
+S 12538000 V 4340000 AUTO
+S 12549000 V 2894000 AUTO
+S 12555000 H 5632000 AUTO
+S 12557000 V 2156000 AUTO
+S 12562000 H 5632000 AUTO
+S 12563000 V 2222000 AUTO
+S 12568000 H 3703000 AUTO
+S 12625000 V 4444000 AUTO
+S 12633000 V 4883000 AUTO
+S 12642000 V 3418000 AUTO
+S 12650000 H 15000000 AUTO
+S 12656000 V 4883000 AUTO
+S 12677000 V 6111000 AUTO
+S 12683000 H 2894000 AUTO
+S 12703000 H 2748000 AUTO
+S 12716000 H 6000000 AUTO
+S 12723000 H 3000000 AUTO
+S 12733000 V 16277000 AUTO
diff --git a/util/scan/dvb-s/Express-3A-11.0W b/util/scan/dvb-s/Express-3A-11.0W
new file mode 100644
index 0000000..1deef03
--- /dev/null
+++ b/util/scan/dvb-s/Express-3A-11.0W
@@ -0,0 +1,4 @@
+# Express 3A @ 11.0W
+# freq pol sr fec
+
+S 3675000 V 29623000 AUTO
diff --git a/util/scan/dvb-s/ExpressAM1-40.0E b/util/scan/dvb-s/ExpressAM1-40.0E
new file mode 100644
index 0000000..3ffbf01
--- /dev/null
+++ b/util/scan/dvb-s/ExpressAM1-40.0E
@@ -0,0 +1,5 @@
+# Express AM1 @ 40E
+# freq pol sr fec
+S 10967000 V 20000000 AUTO
+S 10995000 V 20000000 AUTO
+S 11097000 H 4000000 AUTO
diff --git a/util/scan/dvb-s/ExpressAM2-80.0E b/util/scan/dvb-s/ExpressAM2-80.0E
new file mode 100644
index 0000000..0a9a990
--- /dev/null
+++ b/util/scan/dvb-s/ExpressAM2-80.0E
@@ -0,0 +1,35 @@
+# Express AM2 @ 80E
+# freq pol sr fec
+S 10973000 V 4444000 AUTO
+S 10991000 V 4444000 AUTO
+S 11044000 H 44948000 AUTO
+S 11081000 V 5064000 AUTO
+S 11088000 V 4548000 AUTO
+S 11191000 H 3255000 AUTO
+S 11462000 V 3200000 AUTO
+S 11478000 H 4400000 AUTO
+S 11544000 V 44950000 AUTO
+S 11606000 V 44948000 AUTO
+S 11650000 V 3500000 AUTO
+
+# Express AM2 @ 80E C-BAND
+# Generated by Roman Kashcheev
+# Mar 30, 2008
+# freq pol sr fec
+
+# RSCC
+S 3525000 V 31106000 3/4
+# TRK Sever
+S 3558000 V 3215000 3/4
+# TRV Muji
+S 3562000 V 3225000 3/4
+# OTV Sakhalin
+S 3625000 V 3000000 3/4
+# RSCC
+S 3675000 V 33483000 7/8
+# 5 Kanal
+S 3929000 H 8705000 3/4
+# TV Centr
+S 4147000 V 27500000 3/4
+# Blagovest Telekanal
+S 4175000 V 6510000 3/4
diff --git a/util/scan/dvb-s/ExpressAM22-53.0E b/util/scan/dvb-s/ExpressAM22-53.0E
new file mode 100644
index 0000000..3749e7f
--- /dev/null
+++ b/util/scan/dvb-s/ExpressAM22-53.0E
@@ -0,0 +1,9 @@
+# Express AM 22 @ 53E
+# freq pol sr fec
+S 11044000 V 44950000 3/4
+S 10974000 H 8150000 3/4
+#S 10974000 V 32223000 7/8
+S 11031000 H 3750000 3/4
+S 11096000 V 6400000 3/4
+S 11124000 V 7593000 3/4
+S 11161000 V 5785000 3/4
diff --git a/util/scan/dvb-s/Galaxy10R-123w b/util/scan/dvb-s/Galaxy10R-123w
new file mode 100644
index 0000000..bd915f7
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy10R-123w
@@ -0,0 +1,10 @@
+# Galaxy 10R @ 123W
+# freq pol sr fec
+
+S 11720000 V 27692000 AUTO
+S 11732000 H 13240000 AUTO
+S 11800000 V 26657000 AUTO
+S 11805000 H 04580000 AUTO
+S 11966000 V 13021000 AUTO
+S 12104000 V 02222000 AUTO
+S 12114000 V 04444000 AUTO
diff --git a/util/scan/dvb-s/Galaxy11-91w b/util/scan/dvb-s/Galaxy11-91w
new file mode 100644
index 0000000..81aa25b
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy11-91w
@@ -0,0 +1,49 @@
+# Galaxy 11 @ 91W
+# freq pol sr fec
+
+S 10964000 V 19850000 AUTO
+S 10994000 V 20000000 AUTO
+S 11024000 V 20000000 AUTO
+S 11806000 V 03979000 AUTO
+S 11815000 V 03979000 AUTO
+S 11825000 V 06111000 AUTO
+S 11925000 V 03979000 AUTO
+S 11930000 V 03979000 AUTO
+S 11935000 V 03979000 AUTO
+S 11940000 V 03979000 AUTO
+S 11945000 V 03979000 AUTO
+S 11950000 H 03979000 AUTO
+S 11950000 V 03979000 AUTO
+S 11955000 H 03979000 AUTO
+S 11955000 V 03979000 AUTO
+S 11960000 H 03979000 AUTO
+S 11965000 V 03979000 AUTO
+S 11965000 H 03979000 AUTO
+S 11970000 V 03979000 AUTO
+S 11970000 H 03979000 AUTO
+S 11975000 V 03979000 AUTO
+S 11975000 H 03979000 AUTO
+S 11980000 V 03979000 AUTO
+S 11985000 H 03979000 AUTO
+S 11985000 V 03979000 AUTO
+S 11990000 H 03979000 AUTO
+S 11990000 V 03979000 AUTO
+S 11995000 H 03979000 AUTO
+S 11995000 V 03979000 AUTO
+S 12000000 H 03979000 AUTO
+S 12005000 V 03979000 AUTO
+S 12010000 H 03979000 AUTO
+S 12010000 V 03979000 AUTO
+S 12015000 H 03979000 AUTO
+S 12015000 V 03979000 AUTO
+S 12020000 V 03979000 AUTO
+S 12025000 V 03979000 AUTO
+S 12030000 V 03979000 AUTO
+S 12035000 V 03979000 AUTO
+S 12066000 H 05632000 AUTO
+S 12075000 H 03979000 AUTO
+S 12083000 H 05632000 AUTO
+S 12086000 V 06144000 AUTO
+S 12096000 V 06144000 AUTO
+S 12104000 V 06144000 AUTO
+S 12114000 V 06144000 AUTO
diff --git a/util/scan/dvb-s/Galaxy25-97w b/util/scan/dvb-s/Galaxy25-97w
new file mode 100644
index 0000000..be6e7cc
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy25-97w
@@ -0,0 +1,19 @@
+# Galaxy 25 @ 97W
+# freq pol sr fec
+
+S 11789000 V 28125000 AUTO
+S 11836000 V 20770000 AUTO
+S 11867000 V 22000000 AUTO
+S 11874000 H 22000000 AUTO
+S 11898000 V 22000000 AUTO
+S 11936000 H 20000000 AUTO
+S 11966000 H 22000000 AUTO
+S 11991000 V 22000000 AUTO
+S 11999000 H 20000000 AUTO
+S 12053000 V 22000000 AUTO
+S 12084000 V 22000000 AUTO
+S 12090000 H 20000000 AUTO
+S 12115000 V 22425000 AUTO
+S 12146000 V 22000000 AUTO
+S 12152000 H 20000000 AUTO
+S 12177000 V 23000000 AUTO
diff --git a/util/scan/dvb-s/Galaxy26-93w b/util/scan/dvb-s/Galaxy26-93w
new file mode 100644
index 0000000..9388a1a
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy26-93w
@@ -0,0 +1,58 @@
+# Galaxy 26 @ 93W
+# freq pol sr fec
+
+S 11711000 V 14312000 AUTO
+S 11721000 V 03979000 AUTO
+S 11727000 V 03979000 AUTO
+S 11732000 V 03979000 AUTO
+S 11737000 V 03979000 AUTO
+S 11737000 H 03979000 AUTO
+S 11742000 V 03979000 AUTO
+S 11748000 V 03979000 AUTO
+S 11753000 V 03979000 AUTO
+S 11767000 V 03979000 AUTO
+S 11772000 V 03979000 AUTO
+S 11772000 H 03979000 AUTO
+S 11777000 V 03979000 AUTO
+S 11782000 V 03979000 AUTO
+S 11788000 V 03979000 AUTO
+S 11793000 V 03979000 AUTO
+S 11809000 V 03979000 AUTO
+S 11814000 V 03979000 AUTO
+S 11841000 H 04000000 AUTO
+S 11887000 V 03979000 AUTO
+S 11893000 V 03979000 AUTO
+S 11904000 H 03010000 AUTO
+S 11919000 V 03979000 AUTO
+S 11924000 V 03979000 AUTO
+S 11926000 H 08848000 AUTO
+S 11929000 V 03979000 AUTO
+S 11935000 V 03979000 AUTO
+S 11936000 H 08848000 AUTO
+S 11944000 H 08848000 AUTO
+S 11949000 V 03979000 AUTO
+S 11954000 V 03979000 AUTO
+S 11956000 H 03979000 AUTO
+S 11960000 V 03979000 AUTO
+S 11961000 H 03979000 AUTO
+S 11965000 V 03979000 AUTO
+S 11967000 H 03979000 AUTO
+S 11970000 V 03979000 AUTO
+S 11972000 H 03979000 AUTO
+S 11977000 H 03979000 AUTO
+S 12047000 V 03979000 AUTO
+S 12048000 H 03979000 AUTO
+S 12054000 H 03979000 AUTO
+S 12058000 V 03979000 AUTO
+S 12059000 H 03979000 AUTO
+S 12063000 V 03979000 AUTO
+S 12064000 H 03979000 AUTO
+S 12069000 H 03979000 AUTO
+S 12076000 V 08681000 AUTO
+S 12089000 V 06511000 AUTO
+S 12110000 H 04104000 AUTO
+S 12116000 H 03979000 AUTO
+S 12121000 H 03979000 AUTO
+S 12126000 H 03979000 AUTO
+S 12132000 H 03979000 AUTO
+S 12175000 V 05147000 AUTO
diff --git a/util/scan/dvb-s/Galaxy27-129w b/util/scan/dvb-s/Galaxy27-129w
new file mode 100644
index 0000000..9f8eb78
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy27-129w
@@ -0,0 +1,4 @@
+# Galaxy 27 @ 129W
+# freq pol sr fec
+
+S 11964000 H 02920000 AUTO
diff --git a/util/scan/dvb-s/Galaxy28-89w b/util/scan/dvb-s/Galaxy28-89w
new file mode 100644
index 0000000..15a6e54
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy28-89w
@@ -0,0 +1,41 @@
+# Galaxy 28 @ 89W
+# freq pol sr fec
+
+S 11717000 H 04411000 AUTO
+S 11747000 H 06620000 AUTO
+S 11756000 H 06620000 AUTO
+S 11780000 H 29000000 AUTO
+S 11800000 H 27500000 AUTO
+S 11825000 H 04552000 AUTO
+S 11865000 H 03700000 AUTO
+S 11882000 H 04883000 AUTO
+S 11925000 H 03979000 AUTO
+S 11930000 H 03979000 AUTO
+S 11935000 H 03979000 AUTO
+S 11936000 H 06000000 AUTO
+S 11940000 H 03979000 AUTO
+S 11945000 H 03979000 AUTO
+S 11950000 H 03979000 AUTO
+S 11955000 V 19532000 AUTO
+S 11960000 H 28800000 AUTO
+S 11965000 H 03979000 AUTO
+S 11970000 H 03979000 AUTO
+S 11975000 V 03979000 AUTO
+S 11980000 H 03979000 AUTO
+S 11985000 H 03979000 AUTO
+S 11989000 V 06111000 AUTO
+S 11990000 H 03979000 AUTO
+S 11995000 H 03979000 AUTO
+S 12000000 H 28800000 AUTO
+S 12009000 V 06111000 AUTO
+S 12032000 H 06666000 AUTO
+S 12092000 H 02314000 AUTO
+S 12114000 H 14398000 AUTO
+S 12134000 H 04000000 AUTO
+S 12164000 H 03979000 AUTO
+S 12170000 H 03979000 AUTO
+S 12175000 H 03979000 AUTO
+S 12180000 H 03979000 AUTO
+S 12185000 H 03979000 AUTO
+S 12191000 H 03979000 AUTO
+S 12196000 H 03979000 AUTO
diff --git a/util/scan/dvb-s/Galaxy3C-95w b/util/scan/dvb-s/Galaxy3C-95w
new file mode 100644
index 0000000..9d1e0d6
--- /dev/null
+++ b/util/scan/dvb-s/Galaxy3C-95w
@@ -0,0 +1,4 @@
+# Galaxy 3C @ 95W
+# freq pol sr fec
+
+S 11780000 H 20760000 AUTO
diff --git a/util/scan/dvb-s/Hispasat-30.0W b/util/scan/dvb-s/Hispasat-30.0W
index 2c200b5..a21592b 100644
--- a/util/scan/dvb-s/Hispasat-30.0W
+++ b/util/scan/dvb-s/Hispasat-30.0W
@@ -1,6 +1,43 @@
# Hispasat 30.0W
# freq pol sr fec
+
S 11539000 V 24500000 5/6
+S 11749000 V 03520000 AUTO
+S 11760000 V 03260000 AUTO
+S 11766000 V 04500000 AUTO
+S 11776000 V 02387000 AUTO
+S 11783000 V 01200000 AUTO
+S 11787000 V 02500000 AUTO
+S 11807000 V 06510000 AUTO
+S 11823000 V 02387000 AUTO
+S 11884000 V 27500000 AUTO
+S 11907000 V 02592000 AUTO
+S 11917000 V 05681000 AUTO
S 11931000 H 27500000 3/4
+S 11931000 V 02220000 AUTO
+S 11936000 V 05185000 AUTO
+S 11940000 V 01481000 AUTO
+S 11972000 H 27500000 AUTO
+S 11997000 H 04422000 AUTO
+S 12003000 H 05632000 AUTO
+S 12008000 H 06111000 AUTO
+S 12015000 H 03492000 AUTO
S 12015000 V 27500000 3/4
+S 12040000 H 05632000 AUTO
+S 12052000 V 27500000 AUTO
+S 12085000 H 05632000 AUTO
+S 12131000 H 27500000 AUTO
+S 12135000 V 04444000 AUTO
+S 12137000 V 03030000 AUTO
+S 12141000 V 03255000 AUTO
+S 12146000 V 04200000 AUTO
+S 12156000 V 02222000 AUTO
+S 12158000 V 02348000 AUTO
+S 12163000 V 03030000 AUTO
+S 12168000 V 05240000 AUTO
+S 12172000 H 27500000 AUTO
+S 12175000 V 04500000 AUTO
+S 12182000 V 03340000 AUTO
+S 12188000 V 02583000 AUTO
+S 12192000 V 02593000 AUTO
S 12567000 H 19850000 3/4
diff --git a/util/scan/dvb-s/Hotbird-13.0E b/util/scan/dvb-s/Hotbird-13.0E
index f2168da..7c916a8 100644
--- a/util/scan/dvb-s/Hotbird-13.0E
+++ b/util/scan/dvb-s/Hotbird-13.0E
@@ -1,3 +1,96 @@
# EUTELSAT SkyPlex, Hotbird 13E
# freq pol sr fec
S 12539000 H 27500000 3/4
+S 10719000 V 27500000 3/4
+S 10723000 H 29900000 3/4
+S 10757000 V 27500000 3/4
+S 10775000 H 28000000 3/4
+S 10795000 V 27500000 3/4
+S 10834000 V 27500000 3/4
+S 10853000 H 27500000 3/4
+S 10872000 V 27500000 3/4
+S 10892000 H 27500000 3/4
+S 10910000 V 27500000 3/4
+S 10930000 H 27500000 3/4
+S 10949000 V 27500000 3/4
+S 10971000 H 27500000 3/4
+S 10992000 V 27500000 2/3
+S 11013000 H 27500000 3/4
+S 11034000 V 27500000 3/4
+S 11054000 H 27500000 5/6
+S 11075000 V 27500000 3/4
+S 11095000 H 28000000 3/4
+S 11117000 V 27500000 3/4
+S 11137000 H 27500000 3/4
+S 11158000 V 27500000 3/4
+S 11178000 H 27500000 3/4
+S 11200000 V 27500000 5/6
+S 11219000 H 27500000 3/4
+S 11242000 V 27500000 3/4
+S 11278000 V 27500000 3/4
+S 11295000 H 27500000 3/4
+S 11334000 H 27500000 2/3
+S 11355000 V 27500000 3/4
+S 11373000 H 27500000 2/3
+S 11393000 V 27500000 3/4
+S 11411000 H 27500000 5/6
+S 11432000 V 27500000 2/3
+S 11470000 V 27500000 5/6
+S 11488000 H 27500000 3/4
+S 11526000 H 27500000 3/4
+S 11541000 V 22000000 5/6
+S 11565000 H 27500000 3/4
+S 11585000 V 27500000 3/4
+S 11604000 H 27500000 5/6
+S 11623000 V 27500000 3/4
+S 11645000 H 27500000 3/4
+S 11662000 V 27500000 3/4
+S 11677000 H 27500000 3/4
+S 11727000 V 27500000 3/4
+S 11747000 H 27500000 3/4
+S 11765000 V 27500000 2/3
+S 11785000 H 27500000 3/4
+S 11804000 V 27500000 2/3
+S 11823000 H 27500000 3/4
+S 11842000 V 27500000 3/4
+S 11861000 H 27500000 3/4
+S 11880000 V 27500000 3/4
+S 11900000 H 27500000 3/4
+S 11919000 V 27500000 2/3
+S 11938000 H 27500000 3/4
+S 11958000 V 27500000 3/4
+S 11976000 H 27500000 3/4
+S 12015000 H 27500000 3/4
+S 12034000 V 27500000 3/4
+S 12054000 H 27500000 3/4
+S 12072000 V 27500000 3/4
+S 12092000 H 27500000 3/4
+S 12111000 V 27500000 3/4
+S 12149000 V 27500000 3/4
+S 12169000 H 27500000 3/4
+S 12188000 V 27500000 3/4
+S 12207000 H 27500000 3/4
+S 12226000 V 27500000 3/4
+S 12245000 H 27500000 3/4
+S 12264000 V 27500000 3/4
+S 12284000 H 27500000 3/4
+S 12302000 V 27500000 3/4
+S 12322000 H 27500000 3/4
+S 12341000 V 27500000 3/4
+S 12360000 H 27500000 3/4
+S 12379000 V 27500000 3/4
+S 12398000 H 27500000 3/4
+S 12418000 V 27500000 3/4
+S 12437000 H 27500000 3/4
+S 12475000 H 27500000 3/4
+S 12519000 V 27500000 3/4
+S 12558000 V 27500000 3/4
+S 12577000 H 27500000 3/4
+S 12596000 V 27500000 3/4
+S 12616000 H 27500000 3/4
+S 12635000 V 27500000 3/4
+S 12654000 H 27500000 3/4
+S 12673000 V 27500000 3/4
+S 12692000 H 27500000 3/4
+S 12713000 V 27500000 3/4
+S 12731000 H 27500000 3/4
diff --git a/util/scan/dvb-s/IA5-97w b/util/scan/dvb-s/IA5-97w
new file mode 100644
index 0000000..76c3297
--- /dev/null
+++ b/util/scan/dvb-s/IA5-97w
@@ -0,0 +1,18 @@
+# Intelsat Americas 5 @ 97W
+# freq pol sr fec
+
+S 11789000 V 25000000 AUTO
+S 11836000 V 20765000 AUTO
+S 11867000 V 22000000 AUTO
+S 11874000 H 22000000 AUTO
+S 11898000 V 22000000 AUTO
+S 11966000 H 22000000 AUTO
+S 11991000 V 22000000 AUTO
+S 12053000 V 22000000 AUTO
+S 12084000 V 22000000 AUTO
+S 12090000 H 20000000 AUTO
+S 12115000 V 22425000 AUTO
+S 12122000 H 22000000 AUTO
+S 12146000 V 22000000 AUTO
+S 12152000 H 20000000 AUTO
+S 12177000 V 23000000 AUTO
diff --git a/util/scan/dvb-s/IA6-93w b/util/scan/dvb-s/IA6-93w
new file mode 100644
index 0000000..eb5d93a
--- /dev/null
+++ b/util/scan/dvb-s/IA6-93w
@@ -0,0 +1,61 @@
+# Intelsat Americas 6 @ 93W
+# freq pol sr fec
+
+S 11711000 V 14312000 AUTO
+S 11721000 V 03979000 AUTO
+S 11727000 V 03979000 AUTO
+S 11732000 V 03979000 AUTO
+S 11737000 V 03979000 AUTO
+S 11737000 H 03979000 AUTO
+S 11742000 V 03979000 AUTO
+S 11748000 V 03979000 AUTO
+S 11753000 V 03979000 AUTO
+S 11767000 V 03979000 AUTO
+S 11772000 V 03979000 AUTO
+S 11772000 H 03979000 AUTO
+S 11777000 V 03979000 AUTO
+S 11782000 V 03979000 AUTO
+S 11788000 V 03979000 AUTO
+S 11793000 V 03979000 AUTO
+S 11809000 V 03979000 AUTO
+S 11814000 V 03979000 AUTO
+S 11827000 V 08429000 AUTO
+S 11836000 H 07179000 AUTO
+S 11841000 H 04000000 AUTO
+S 11865000 V 03516000 AUTO
+S 11887000 V 03979000 AUTO
+S 11893000 V 03979000 AUTO
+S 11904000 V 05000000 AUTO
+S 11919000 V 03979000 AUTO
+S 11924000 V 03979000 AUTO
+S 11926000 H 08848000 AUTO
+S 11929000 V 03979000 AUTO
+S 11935000 V 03979000 AUTO
+S 11936000 H 08848000 AUTO
+S 11944000 H 08848000 AUTO
+S 11949000 V 03979000 AUTO
+S 11954000 V 03979000 AUTO
+S 11956000 H 03979000 AUTO
+S 11960000 V 03979000 AUTO
+S 11961000 H 03979000 AUTO
+S 11965000 V 03979000 AUTO
+S 11967000 H 03979000 AUTO
+S 11970000 V 03979000 AUTO
+S 11972000 H 03979000 AUTO
+S 11977000 H 03979000 AUTO
+S 12047000 V 03979000 AUTO
+S 12048000 H 03979000 AUTO
+S 12054000 H 03979000 AUTO
+S 12058000 V 03979000 AUTO
+S 12059000 H 03979000 AUTO
+S 12063000 V 03979000 AUTO
+S 12064000 H 03979000 AUTO
+S 12069000 H 03979000 AUTO
+S 12076000 V 08679000 AUTO
+S 12089000 V 06511000 AUTO
+S 12110000 H 04104000 AUTO
+S 12116000 H 03979000 AUTO
+S 12121000 H 03979000 AUTO
+S 12126000 H 03979000 AUTO
+S 12132000 H 03979000 AUTO
+S 12175000 V 05147000 AUTO
diff --git a/util/scan/dvb-s/IA7-129w b/util/scan/dvb-s/IA7-129w
new file mode 100644
index 0000000..0be1d6e
--- /dev/null
+++ b/util/scan/dvb-s/IA7-129w
@@ -0,0 +1,4 @@
+# Intelsat Americas 7 @ 129W
+# freq pol sr fec
+
+S 11989000 H 02821000 AUTO
diff --git a/util/scan/dvb-s/IA8-89w b/util/scan/dvb-s/IA8-89w
new file mode 100644
index 0000000..ba1dd84
--- /dev/null
+++ b/util/scan/dvb-s/IA8-89w
@@ -0,0 +1,34 @@
+# Intelsat Americas 8 @ 89W
+# freq pol sr fec
+
+S 11780000 H 29000000 AUTO
+S 11925000 H 03979000 AUTO
+S 11930000 H 03979000 AUTO
+S 11935000 H 03979000 AUTO
+S 11940000 H 03979000 AUTO
+S 11945000 H 03979000 AUTO
+S 11945000 V 03979000 AUTO
+S 11950000 H 03979000 AUTO
+S 11950000 V 03979000 AUTO
+S 11955000 H 03979000 AUTO
+S 11955000 V 03979000 AUTO
+S 11960000 V 03979000 AUTO
+S 11965000 V 03979000 AUTO
+S 11965000 H 03979000 AUTO
+S 11970000 V 03979000 AUTO
+S 11970000 H 03979000 AUTO
+S 11975000 V 03979000 AUTO
+S 11975000 H 03979000 AUTO
+S 11980000 H 03979000 AUTO
+S 11985000 H 03979000 AUTO
+S 11989000 V 06111000 AUTO
+S 11990000 H 03979000 AUTO
+S 11995000 H 03979000 AUTO
+S 12009000 V 06111000 AUTO
+S 12164000 H 03979000 AUTO
+S 12170000 H 03979000 AUTO
+S 12175000 H 03979000 AUTO
+S 12180000 H 03979000 AUTO
+S 12185000 H 03979000 AUTO
+S 12191000 H 03979000 AUTO
+S 12196000 H 03979000 AUTO
diff --git a/util/scan/dvb-s/Intel4-72.0E b/util/scan/dvb-s/Intel4-72.0E
new file mode 100644
index 0000000..3a7b640
--- /dev/null
+++ b/util/scan/dvb-s/Intel4-72.0E
@@ -0,0 +1,6 @@
+# Intel4 @ 72E
+# freq pol sr fec
+S 11533000 V 4220000 AUTO
+S 11638000 H 5632000 AUTO
+S 12518000 V 8232000 AUTO
+S 12526000 V 3266000 AUTO
diff --git a/util/scan/dvb-s/Intel904-60.0E b/util/scan/dvb-s/Intel904-60.0E
new file mode 100644
index 0000000..d39362c
--- /dev/null
+++ b/util/scan/dvb-s/Intel904-60.0E
@@ -0,0 +1,13 @@
+# Intel904 @ 60E
+# freq pol sr fec
+S 11003000 H 2975000 AUTO
+S 11011000 H 2975000 AUTO
+S 11015000 H 2975000 AUTO
+S 11093000 V 3980000 AUTO
+S 11101000 V 4105000 AUTO
+S 11142000 H 2963000 AUTO
+S 11152000 H 2963000 AUTO
+S 11157000 H 2963000 AUTO
+S 11515000 V 7300000 AUTO
+S 11635000 V 29700000 AUTO
+S 11675000 V 29700000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-1002-1.0W b/util/scan/dvb-s/Intelsat-1002-1.0W
new file mode 100644
index 0000000..09d82ca
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-1002-1.0W
@@ -0,0 +1,5 @@
+# Intelsat 1002 @ 1.0W
+# freq pol sr fec
+
+S 4175000 V 28000000 AUTO
+S 4180000 H 21050000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-11-43.0W b/util/scan/dvb-s/Intelsat-11-43.0W
new file mode 100644
index 0000000..424f78a
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-11-43.0W
@@ -0,0 +1,4 @@
+# Intelsat 11 @ 43.0W
+# freq pol sr fec
+
+S 3944000 H 05945000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-1R-45.0W b/util/scan/dvb-s/Intelsat-1R-45.0W
new file mode 100644
index 0000000..15f6574
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-1R-45.0W
@@ -0,0 +1,44 @@
+# Intelsat 1R @ 45.0W
+# freq pol sr fec
+
+S 4104000 V 14450000 AUTO
+S 3854000 H 02370000 AUTO
+S 11893000 H 06620000 AUTO
+S 3869000 H 03515000 AUTO
+S 4186000 V 02000000 AUTO
+S 4040000 V 04347000 AUTO
+S 4071000 V 02615000 AUTO
+S 3991000 V 04044000 AUTO
+S 3882000 V 04410000 AUTO
+S 11788000 V 10000000 AUTO
+S 11728000 V 05057000 AUTO
+S 11737000 V 05057000 AUTO
+S 11722000 V 03000000 AUTO
+S 11718000 H 24667000 AUTO
+S 11833000 H 17360000 AUTO
+S 11930000 V 11790000 AUTO
+S 11808000 H 04779000 AUTO
+S 4132000 H 05749000 AUTO
+S 3780000 V 02941000 AUTO
+S 11705000 V 04440000 AUTO
+S 3759000 V 02941000 AUTO
+S 4171000 V 04410000 AUTO
+S 3899000 V 06611000 AUTO
+S 4192000 H 02075000 AUTO
+S 4096000 H 08102000 AUTO
+S 11873000 H 06000000 AUTO
+S 11856000 V 03000000 AUTO
+S 11746000 V 06900000 AUTO
+S 11715000 V 05500000 AUTO
+S 3985000 V 03310000 AUTO
+S 3892000 V 06110000 AUTO
+S 4135000 H 26600000 AUTO
+S 4121000 H 03510000 AUTO
+S 3742000 V 04444000 AUTO
+S 3910000 V 04292000 AUTO
+S 3975000 V 03310000 AUTO
+S 4133000 V 03255000 AUTO
+S 3785000 V 04409000 AUTO
+S 3868000 V 10075000 AUTO
+S 3774000 V 08820000 AUTO
+S 4128000 V 03310000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-3R-43.0W b/util/scan/dvb-s/Intelsat-3R-43.0W
new file mode 100644
index 0000000..d64bc5b
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-3R-43.0W
@@ -0,0 +1,35 @@
+# Intelsat 3R @ 43.0W
+# freq pol sr fec
+
+S 3936000 H 03310000 AUTO
+S 3901000 V 06620000 AUTO
+S 3891000 V 06111000 AUTO
+S 3935000 V 17360000 AUTO
+S 3872000 H 06620000 AUTO
+S 3736000 H 29270000 AUTO
+S 4106000 V 26470000 AUTO
+S 3910000 V 05632000 AUTO
+S 3919000 V 06620000 AUTO
+S 4083000 V 06599000 AUTO
+S 4106000 H 29270000 AUTO
+S 3994000 H 21090000 AUTO
+S 3867000 V 06429000 AUTO
+S 3958000 V 06500000 AUTO
+S 3980000 V 03500000 AUTO
+S 3828000 V 04350000 AUTO
+S 3888000 H 07813000 AUTO
+S 3785000 H 30800000 AUTO
+S 3942000 V 01200000 AUTO
+S 3946000 V 02592000 AUTO
+S 3988000 V 04070000 AUTO
+S 3845000 H 30800000 AUTO
+S 4040000 H 30800000 AUTO
+S 3865000 V 06900000 AUTO
+S 3850000 V 28800000 AUTO
+S 11705000 H 03700000 AUTO
+S 11745000 H 03111000 AUTO
+S 11711000 H 04687000 AUTO
+S 11754000 H 03109000 AUTO
+S 3746000 V 21261000 AUTO
+S 4150000 H 24570000 AUTO
+S 3930000 H 02812000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-6B-43.0W b/util/scan/dvb-s/Intelsat-6B-43.0W
new file mode 100644
index 0000000..a8b4d7a
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-6B-43.0W
@@ -0,0 +1,17 @@
+# Intelsat 6B @ 43.0W
+# freq pol sr fec
+
+S 10882000 H 30000000 AUTO
+S 10882000 V 30000000 AUTO
+S 10970000 H 30000000 AUTO
+S 10970000 V 30000000 AUTO
+S 11050000 H 30000000 AUTO
+S 11130000 H 30000000 AUTO
+S 11382000 V 30000000 AUTO
+S 11130000 V 30000000 AUTO
+S 10720000 H 30000000 AUTO
+S 10720000 V 30000000 AUTO
+S 11050000 V 30000000 AUTO
+S 11382000 H 30000000 AUTO
+S 10800000 H 30000000 AUTO
+S 10800000 V 30000000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-705-50.0W b/util/scan/dvb-s/Intelsat-705-50.0W
new file mode 100644
index 0000000..48aeec0
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-705-50.0W
@@ -0,0 +1,7 @@
+# Intelsat 705 @ 50.0W
+# freq pol sr fec
+
+S 3911000 V 03617000 AUTO
+S 3917000 V 04087000 AUTO
+S 3838000 H 07053000 AUTO
+S 4126000 H 06111000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-707-53.0W b/util/scan/dvb-s/Intelsat-707-53.0W
new file mode 100644
index 0000000..56dd65f
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-707-53.0W
@@ -0,0 +1,5 @@
+# Intelsat 707 @ 53.0W
+# freq pol sr fec
+
+S 3820000 V 03255000 AUTO
+S 11483000 V 05333000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-805-55.5W b/util/scan/dvb-s/Intelsat-805-55.5W
new file mode 100644
index 0000000..3d4cff5
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-805-55.5W
@@ -0,0 +1,67 @@
+# Intelsat 805 @ 55.5W
+# freq pol sr fec
+
+S 4171000 H 06111000 AUTO
+S 4147000 H 06111000 AUTO
+S 3914000 V 01809000 AUTO
+S 3572000 V 11800000 AUTO
+S 4135000 H 06111000 AUTO
+S 3737000 H 01809000 AUTO
+S 3932000 V 03255000 AUTO
+S 3759000 V 04167000 AUTO
+S 3750000 V 05632000 AUTO
+S 3850000 H 20000000 AUTO
+S 4010000 V 06111000 AUTO
+S 3715000 H 08890000 AUTO
+S 3670000 H 01374000 AUTO
+S 4158000 H 01447000 AUTO
+S 3549000 V 06510000 AUTO
+S 3451000 H 04444000 AUTO
+S 3667000 H 03300000 AUTO
+S 3522000 H 30000000 AUTO
+S 4055000 V 21703000 AUTO
+S 3698000 V 03600000 AUTO
+S 4119000 V 01631000 AUTO
+S 3446000 H 03200000 AUTO
+S 3675000 V 02660000 AUTO
+S 3717000 V 11574000 AUTO
+S 4030000 V 06111000 AUTO
+S 3767000 H 04427000 AUTO
+S 4027000 V 02000000 AUTO
+S 4089000 V 05540000 AUTO
+S 3685000 V 05632000 AUTO
+S 3751000 H 05632000 AUTO
+S 4127000 V 02000000 AUTO
+S 3980000 V 19510000 AUTO
+S 3590000 V 10127000 AUTO
+S 4000000 V 05200000 AUTO
+S 3762000 H 03662000 AUTO
+S 3936000 H 03255000 AUTO
+S 3727000 H 03000000 AUTO
+S 4104000 H 05062000 AUTO
+S 3777000 H 07400000 AUTO
+S 3431000 H 03500000 AUTO
+S 3478000 V 05632000 AUTO
+S 4093000 H 02540000 AUTO
+S 3929000 H 02941000 AUTO
+S 4195000 H 04444000 AUTO
+S 4140000 V 04700000 AUTO
+S 4096000 H 05247000 AUTO
+S 3467000 V 04340000 AUTO
+S 3442000 H 03000000 AUTO
+S 4080000 V 04340000 AUTO
+S 4084000 H 10317000 AUTO
+S 3723000 H 03000000 AUTO
+S 3815000 H 26667000 AUTO
+S 4006000 V 03690000 AUTO
+S 3918000 V 04400000 AUTO
+S 3735000 V 08680000 AUTO
+S 3727000 V 03000000 AUTO
+S 3940000 H 02575000 AUTO
+S 3792000 H 02244000 AUTO
+S 3900000 H 03612000 AUTO
+S 3677000 H 04232000 AUTO
+S 4127000 H 02532000 AUTO
+S 4152000 V 03600000 AUTO
+S 4177000 V 27690000 AUTO
+S 4111000 H 03333000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-9-58.0W b/util/scan/dvb-s/Intelsat-9-58.0W
new file mode 100644
index 0000000..e8605a9
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-9-58.0W
@@ -0,0 +1,58 @@
+# Intelsat 9 @ 58.0W
+# freq pol sr fec
+
+S 4122000 H 02222000 AUTO
+S 4146000 H 06620000 AUTO
+S 4157000 H 06620000 AUTO
+S 4160000 V 03000000 AUTO
+S 3960000 V 29270000 AUTO
+S 3960000 H 29270000 AUTO
+S 4080000 H 27684000 AUTO
+S 3720000 H 19510000 AUTO
+S 4131000 H 04444000 AUTO
+S 4155000 H 06111000 AUTO
+S 4173000 H 06620000 AUTO
+S 3995000 H 05632000 AUTO
+S 3986000 H 06111000 AUTO
+S 4175000 H 04410000 AUTO
+S 4107000 H 08850000 AUTO
+S 3925000 H 06666000 AUTO
+S 3905000 H 06620000 AUTO
+S 3915000 H 06620000 AUTO
+S 3925000 H 06620000 AUTO
+S 4005000 H 06620000 AUTO
+S 4015000 H 06620000 AUTO
+S 3720000 V 27700000 AUTO
+S 4166000 H 06200000 AUTO
+S 3794000 H 03332000 AUTO
+S 3807000 H 03428000 AUTO
+S 3880000 V 27690000 AUTO
+S 3800000 V 26470000 AUTO
+S 3760000 V 27690000 AUTO
+S 3996000 H 03330000 AUTO
+S 3935000 H 05632000 AUTO
+S 11852000 V 30000000 AUTO
+S 11895000 V 20000000 AUTO
+S 11913000 V 10000000 AUTO
+S 4155000 V 03310000 AUTO
+S 3934000 V 07000000 AUTO
+S 3787000 H 07407000 AUTO
+S 3924000 V 06620000 AUTO
+S 3800000 H 04444000 AUTO
+S 3911000 V 13330000 AUTO
+S 4040000 H 16180000 AUTO
+S 4080000 V 27690000 AUTO
+S 4144000 V 02205000 AUTO
+S 4151000 V 02890000 AUTO
+S 4147000 V 02941000 AUTO
+S 4170000 V 02941000 AUTO
+S 3760000 H 28500000 AUTO
+S 4120000 V 27500000 AUTO
+S 11670000 V 16470000 AUTO
+S 4125000 H 02941000 AUTO
+S 4137000 H 02941000 AUTO
+S 3880000 H 27690000 AUTO
+S 4174000 V 02941000 AUTO
+S 3840000 V 27690000 AUTO
+S 3840000 H 27690000 AUTO
+S 3815000 H 06250000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-903-34.5W b/util/scan/dvb-s/Intelsat-903-34.5W
new file mode 100644
index 0000000..141c42c
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-903-34.5W
@@ -0,0 +1,7 @@
+# Intelsat 903 @ 34.5W
+# freq pol sr fec
+
+S 4178000 V 32555000 AUTO
+S 4045000 H 04960000 AUTO
+S 3895000 H 13021000 AUTO
+S 4004000 V 02170000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-905-24.5W b/util/scan/dvb-s/Intelsat-905-24.5W
new file mode 100644
index 0000000..c5b1c21
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-905-24.5W
@@ -0,0 +1,9 @@
+# Intelsat 905 @ 24.5W
+# freq pol sr fec
+
+S 4171000 V 06111000 AUTO
+S 4181000 V 06111000 AUTO
+S 4194000 V 05193000 AUTO
+S 4162000 V 06111000 AUTO
+S 4060000 V 06111000 AUTO
+S 4070000 V 06111000 AUTO
diff --git a/util/scan/dvb-s/Intelsat-907-27.5W b/util/scan/dvb-s/Intelsat-907-27.5W
new file mode 100644
index 0000000..c12f549
--- /dev/null
+++ b/util/scan/dvb-s/Intelsat-907-27.5W
@@ -0,0 +1,9 @@
+# Intelsat 907 @ 27.5W
+# freq pol sr fec
+
+S 3873000 H 04687000 AUTO
+S 3935000 H 04687000 AUTO
+S 3743000 V 02900000 AUTO
+S 3732000 V 14000000 AUTO
+S 3943000 H 01808000 AUTO
+S 3938000 H 03544000 AUTO
diff --git a/util/scan/dvb-s/NSS-10-37.5W b/util/scan/dvb-s/NSS-10-37.5W
new file mode 100644
index 0000000..3ebaa71
--- /dev/null
+++ b/util/scan/dvb-s/NSS-10-37.5W
@@ -0,0 +1,12 @@
+# NSS 10 @ 37.5W
+# freq pol sr fec
+
+S 4055000 V 02700000 AUTO
+S 3824000 H 01808000 AUTO
+S 4059000 V 03214000 AUTO
+S 3828000 H 02532000 AUTO
+S 3844000 H 04340000 AUTO
+S 4071000 V 03150000 AUTO
+S 4051000 V 04440000 AUTO
+S 4044000 V 03250000 AUTO
+S 4077000 V 03200000 AUTO
diff --git a/util/scan/dvb-s/NSS-7-22.0W b/util/scan/dvb-s/NSS-7-22.0W
new file mode 100644
index 0000000..e1eefaf
--- /dev/null
+++ b/util/scan/dvb-s/NSS-7-22.0W
@@ -0,0 +1,25 @@
+# NSS 7 @ 22.0W
+# freq pol sr fec
+
+S 3926000 H 03715000 AUTO
+S 3920000 H 03715000 AUTO
+S 3954000 V 05632000 AUTO
+S 3929000 V 05632000 AUTO
+S 3915000 H 03715000 AUTO
+S 3761000 V 22650000 AUTO
+S 11825000 H 05904000 AUTO
+S 12162000 H 06510000 AUTO
+S 11777000 H 04000000 AUTO
+S 11860000 H 35000000 AUTO
+S 12049000 H 06500000 AUTO
+S 11921000 H 35000000 AUTO
+S 4003000 H 06667000 AUTO
+S 4011000 H 06667000 AUTO
+S 4126000 H 03680000 AUTO
+S 3969000 H 01808000 AUTO
+S 3976000 H 01842000 AUTO
+S 11814000 H 05630000 AUTO
+S 4038000 V 03690000 AUTO
+S 3674000 V 02222000 AUTO
+S 4033000 V 03689000 AUTO
+S 4016000 H 03663000 AUTO
diff --git a/util/scan/dvb-s/NSS-806-40.5W b/util/scan/dvb-s/NSS-806-40.5W
new file mode 100644
index 0000000..8bea0a8
--- /dev/null
+++ b/util/scan/dvb-s/NSS-806-40.5W
@@ -0,0 +1,108 @@
+# NSS 806 @ 40.5W
+# freq pol sr fec
+
+S 11921000 H 35000000 AUTO
+S 3660000 H 04350000 AUTO
+S 3986000 H 03179000 AUTO
+S 3859000 H 02600000 AUTO
+S 4120000 V 02960000 AUTO
+S 4016000 V 05712000 AUTO
+S 3978000 H 03978000 AUTO
+S 4100000 V 06111000 AUTO
+S 3965000 V 02540000 AUTO
+S 3774000 H 06670000 AUTO
+S 3725000 V 26667000 AUTO
+S 3600000 V 25185000 AUTO
+S 3758000 V 26667000 AUTO
+S 3982000 V 17800000 AUTO
+S 4090000 V 02515000 AUTO
+S 4042000 H 08680000 AUTO
+S 4009000 V 06666000 AUTO
+S 4003000 H 06666000 AUTO
+S 3648000 H 02000000 AUTO
+S 3664000 V 02170000 AUTO
+S 3644000 H 02534000 AUTO
+S 3695000 H 02963000 AUTO
+S 4082000 H 06666000 AUTO
+S 4143000 V 04800000 AUTO
+S 3641000 V 02666000 AUTO
+S 3991000 H 03578000 AUTO
+S 4000000 H 02450000 AUTO
+S 4009000 H 02450000 AUTO
+S 3960000 V 03170000 AUTO
+S 3755000 H 20000000 AUTO
+S 4135000 V 02000000 AUTO
+S 4005000 H 02450000 AUTO
+S 4003000 H 02450000 AUTO
+S 3600000 H 29185000 AUTO
+S 3868000 V 02100000 AUTO
+S 3685000 H 06500000 AUTO
+S 3688000 V 06666000 AUTO
+S 3679000 V 02220000 AUTO
+S 3961000 H 01481000 AUTO
+S 4130000 V 02000000 AUTO
+S 3923000 H 27500000 AUTO
+S 4052000 V 02459000 AUTO
+S 4071000 V 03333000 AUTO
+S 4146000 H 02571000 AUTO
+S 3646000 V 03978000 AUTO
+S 3837000 H 19510000 AUTO
+S 4132000 H 02480000 AUTO
+S 3653000 V 05924000 AUTO
+S 4055000 H 07233000 AUTO
+S 3938000 V 04785000 AUTO
+S 4152000 V 03280000 AUTO
+S 3832000 V 13310000 AUTO
+S 4090000 H 06620000 AUTO
+S 4082000 V 06510000 AUTO
+S 4107000 V 02100000 AUTO
+S 3500000 H 06666000 AUTO
+S 4126000 V 02531000 AUTO
+S 3860000 V 02713000 AUTO
+S 3983000 H 02222000 AUTO
+S 4065000 H 08400000 AUTO
+S 4063000 V 08500000 AUTO
+S 3972000 H 03330000 AUTO
+S 4024000 H 16030000 AUTO
+S 3803000 V 26860000 AUTO
+S 3920000 V 20000000 AUTO
+S 4053000 V 06666000 AUTO
+S 3676000 V 03000000 AUTO
+S 3637000 H 02963000 AUTO
+S 3516000 V 05632000 AUTO
+S 3516000 H 05632000 AUTO
+S 4093000 V 02887000 AUTO
+S 4177000 H 04391000 AUTO
+S 4124000 H 03480000 AUTO
+S 4139000 V 02220000 AUTO
+S 3693000 V 04441000 AUTO
+S 4194000 H 06660000 AUTO
+S 3803000 H 27500000 AUTO
+S 4112000 V 02000000 AUTO
+S 3676000 H 05900000 AUTO
+S 3652000 H 04000000 AUTO
+S 3725000 H 26669000 AUTO
+S 3898000 V 04195000 AUTO
+S 4162000 H 07200000 AUTO
+S 4168000 H 02400000 AUTO
+S 3965000 H 03332000 AUTO
+S 4100000 H 06654000 AUTO
+S 4127000 H 03000000 AUTO
+S 4109000 H 06654000 AUTO
+S 3670000 H 02960000 AUTO
+S 3853000 H 05900000 AUTO
+S 3660000 V 02540000 AUTO
+S 4170000 H 02222000 AUTO
+S 3630000 H 05632000 AUTO
+S 3695000 V 02220000 AUTO
+S 4184000 H 06142000 AUTO
+S 4122000 V 01860000 AUTO
+S 4022000 V 03800000 AUTO
+S 4137000 H 04400000 AUTO
+S 3878000 V 22117000 AUTO
+S 4132000 V 02800000 AUTO
+S 4043000 V 07440000 AUTO
+S 4142000 H 02222000 AUTO
+S 3990000 V 04195000 AUTO
+S 3667000 V 03340000 AUTO
+S 3673000 V 03000000 AUTO
diff --git a/util/scan/dvb-s/Nahuel-1-71.8W b/util/scan/dvb-s/Nahuel-1-71.8W
new file mode 100644
index 0000000..82845bb
--- /dev/null
+++ b/util/scan/dvb-s/Nahuel-1-71.8W
@@ -0,0 +1,11 @@
+# Nahuel 1 @ 71.8W
+# freq pol sr fec
+
+S 11673000 V 04000000 AUTO
+S 11680000 V 03335000 AUTO
+S 11654000 V 04170000 AUTO
+S 11874000 V 04000000 AUTO
+S 12136000 V 02960000 AUTO
+S 11873000 H 08000000 AUTO
+S 12116000 H 14396000 AUTO
+S 11997000 V 08500000 AUTO
diff --git a/util/scan/dvb-s/Nilesat101+102-7.0W b/util/scan/dvb-s/Nilesat101+102-7.0W
new file mode 100644
index 0000000..64c1921
--- /dev/null
+++ b/util/scan/dvb-s/Nilesat101+102-7.0W
@@ -0,0 +1,36 @@
+# Nilesat 101/102 & Atlantic Bird @ 7W
+# freq pol sr fec
+S 10758000 V 27500000 AUTO
+S 10796000 V 27500000 AUTO
+S 10853000 H 27500000 AUTO
+S 10873000 V 27500000 AUTO
+S 10892000 H 27500000 AUTO
+S 10911000 V 27500000 AUTO
+S 10930000 H 27500000 AUTO
+S 11747000 V 27500000 AUTO
+S 11766000 H 27500000 AUTO
+S 11785000 V 27500000 AUTO
+S 11804000 H 27500000 AUTO
+S 11823000 V 27500000 AUTO
+S 11843000 H 27500000 AUTO
+S 11862000 V 27500000 AUTO
+S 11881000 H 27500000 AUTO
+S 11900000 V 27500000 AUTO
+S 11919000 H 27500000 AUTO
+S 11938000 V 27500000 AUTO
+S 11958000 H 27500000 AUTO
+S 11977000 V 27500000 AUTO
+S 11996000 H 27500000 AUTO
+S 12015000 V 27500000 AUTO
+S 12034000 H 27500000 AUTO
+S 12054000 V 27500000 AUTO
+S 12073000 H 27500000 AUTO
+S 12130000 V 27500000 AUTO
+S 12149000 H 27500000 AUTO
+S 12207000 V 27500000 AUTO
+S 12226000 H 27500000 AUTO
+S 12284000 V 27500000 AUTO
+S 12303000 H 27500000 AUTO
+S 12341000 V 27500000 AUTO
+S 12360000 H 27500000 AUTO
+S 12399000 H 27500000 AUTO
diff --git a/util/scan/dvb-s/OptusC1-156E b/util/scan/dvb-s/OptusC1-156E
new file mode 100644
index 0000000..0e3e73b
--- /dev/null
+++ b/util/scan/dvb-s/OptusC1-156E
@@ -0,0 +1,20 @@
+# Optus C1 satellite 156E
+# freq pol sr fec
+S 12278000 H 30000000 2/3
+S 12305000 H 30000000 2/3
+S 12358000 H 27000000 2/3
+S 12398000 H 27800000 3/4
+S 12407000 V 30000000 2/3
+S 12438000 H 27800000 3/4
+S 12487000 V 27800000 3/4
+S 12501000 H 29473000 3/4
+S 12518000 H 27800000 3/4
+S 12527000 V 30000000 3/4
+S 12558000 H 27800000 3/4
+S 12564000 H 29473000 3/4
+S 12567000 V 27800000 2/3
+S 12598000 H 27800000 3/4
+S 12607000 V 29473000 3/4
+S 12638000 H 27800000 3/4
+S 12689000 H 27800000 3/4
+S 12720000 V 30000000 3/4
diff --git a/util/scan/dvb-s/SBS6-74w b/util/scan/dvb-s/SBS6-74w
new file mode 100644
index 0000000..f99e311
--- /dev/null
+++ b/util/scan/dvb-s/SBS6-74w
@@ -0,0 +1,4 @@
+# SBS 6 @ 74W
+# freq pol sr fec
+
+S 11744000 H 06616000 AUTO
diff --git a/util/scan/dvb-s/Satmex-5-116.8W b/util/scan/dvb-s/Satmex-5-116.8W
new file mode 100644
index 0000000..f0522bf
--- /dev/null
+++ b/util/scan/dvb-s/Satmex-5-116.8W
@@ -0,0 +1,72 @@
+# Satmex 5 @ 116.8W
+# freq pol sr fec
+
+S 12034000 H 02532000 AUTO
+S 12175000 H 04232000 AUTO
+S 4060000 H 19510000 AUTO
+S 3905000 V 02963000 AUTO
+S 4084000 H 03162000 AUTO
+S 3767000 H 01620000 AUTO
+S 11975000 H 05000000 AUTO
+S 11960000 H 02000000 AUTO
+S 4180000 H 19510000 AUTO
+S 4115000 H 03253000 AUTO
+S 3840000 V 29270000 AUTO
+S 4160000 V 29270000 AUTO
+S 3940000 H 28125000 AUTO
+S 4052000 V 04307000 AUTO
+S 12024000 H 03000000 AUTO
+S 4134000 H 03617000 AUTO
+S 12028000 H 03255000 AUTO
+S 12060000 V 03078000 AUTO
+S 4012000 V 03131000 AUTO
+S 3949000 V 03255000 AUTO
+S 4076000 H 02962000 AUTO
+S 3749000 H 04070000 AUTO
+S 3744000 H 04480000 AUTO
+S 3755000 H 04000000 AUTO
+S 3869000 H 03000000 AUTO
+S 3876000 H 02170000 AUTO
+S 3879000 H 01984000 AUTO
+S 3957000 V 02600000 AUTO
+S 3975000 V 03131000 AUTO
+S 3982000 H 02531000 AUTO
+S 3832000 H 02500000 AUTO
+S 3953000 V 02597000 AUTO
+S 3987000 V 08860000 AUTO
+S 3996000 V 02170000 AUTO
+S 3748000 V 02100000 AUTO
+S 3932000 V 02500000 AUTO
+S 3914000 V 03223000 AUTO
+S 3888000 H 05351000 AUTO
+S 3805000 V 04679000 AUTO
+S 4001000 V 04100000 AUTO
+S 4023000 H 06400000 AUTO
+S 12176000 H 03985000 AUTO
+S 4108000 H 02666000 AUTO
+S 4038000 V 07675000 AUTO
+S 3809000 V 03100000 AUTO
+S 4080000 V 29270000 AUTO
+S 3910000 H 02500000 AUTO
+S 4164000 H 01733000 AUTO
+S 12193000 V 07885000 AUTO
+S 12164000 V 02000000 AUTO
+S 12044000 V 04340000 AUTO
+S 3720000 V 27000000 AUTO
+S 3922000 V 09760000 AUTO
+S 3797000 V 03200000 AUTO
+S 3968000 V 07500000 AUTO
+S 4037000 H 02222000 AUTO
+S 4046000 H 02441000 AUTO
+S 4080000 H 02441000 AUTO
+S 3773000 V 02892000 AUTO
+S 3767000 V 02893000 AUTO
+S 3935000 V 04440000 AUTO
+S 3972000 H 03364000 AUTO
+S 3905000 H 02400000 AUTO
+S 4007000 V 05582000 AUTO
+S 3885000 H 03000000 AUTO
+S 3826000 H 02712000 AUTO
+S 3944000 V 03410000 AUTO
+S 3915000 H 01520000 AUTO
+S 3876000 V 02920000 AUTO
diff --git a/util/scan/dvb-s/Satmex-6-113.0W b/util/scan/dvb-s/Satmex-6-113.0W
new file mode 100644
index 0000000..8ff01b8
--- /dev/null
+++ b/util/scan/dvb-s/Satmex-6-113.0W
@@ -0,0 +1,19 @@
+# Satmex 6 @ 113.0W
+# freq pol sr fec
+
+S 4078000 H 03609000 AUTO
+S 4080000 V 03255000 AUTO
+S 12145000 V 03255000 AUTO
+S 4085000 V 02821000 AUTO
+S 12126000 V 06022000 AUTO
+S 12166000 H 17500000 AUTO
+S 4075000 V 03782000 AUTO
+S 4091000 V 03720000 AUTO
+S 3985000 V 02300000 AUTO
+S 12126000 H 02170000 AUTO
+S 12157000 V 03038000 AUTO
+S 12091000 V 03337000 AUTO
+S 3947000 V 03700000 AUTO
+S 3761000 V 02120000 AUTO
+S 12107000 V 02222000 AUTO
+S 12080000 H 25635000 AUTO
diff --git a/util/scan/dvb-s/Telstar-12-15.0W b/util/scan/dvb-s/Telstar-12-15.0W
new file mode 100644
index 0000000..fb902ab
--- /dev/null
+++ b/util/scan/dvb-s/Telstar-12-15.0W
@@ -0,0 +1,32 @@
+# Telstar 12 @ 15.0W
+# freq pol sr fec
+
+S 12180000 H 03255000 AUTO
+S 11895000 V 05000000 AUTO
+S 11974000 V 03400000 AUTO
+S 12185000 H 04214000 AUTO
+S 12081000 H 03935000 AUTO
+S 12050000 V 03198000 AUTO
+S 11756000 H 06666000 AUTO
+S 12093000 V 02000000 AUTO
+S 11916000 H 06111000 AUTO
+S 11707000 H 03198000 AUTO
+S 11718000 V 05632000 AUTO
+S 11740000 V 03255000 AUTO
+S 12000000 H 06666000 AUTO
+S 12116000 H 02062000 AUTO
+S 12111000 H 02062000 AUTO
+S 12175000 H 03504000 AUTO
+S 12167000 H 03502000 AUTO
+S 12129000 V 02000000 AUTO
+S 12110000 V 06620000 AUTO
+S 11724000 H 13225000 AUTO
+S 11984000 H 13570000 AUTO
+S 12125000 H 03800000 AUTO
+S 11713000 V 09626000 AUTO
+S 11804000 V 07595000 AUTO
+S 11965000 H 14714000 AUTO
+S 12039000 V 05632000 AUTO
+S 12082000 V 06396000 AUTO
+S 12087000 V 03198000 AUTO
+S 12097000 V 03198000 AUTO
diff --git a/util/scan/dvb-s/Turksat-42.0E b/util/scan/dvb-s/Turksat-42.0E
index 1ac7fd8..2364673 100644
--- a/util/scan/dvb-s/Turksat-42.0E
+++ b/util/scan/dvb-s/Turksat-42.0E
@@ -2,3 +2,4 @@
# freq pol sr fec
S 11594000 H 4557000 5/6
S 10978000 V 2344000 3/4
+S 11734000 H 3291000 3/4
diff --git a/util/scan/dvb-s/Yamal201-90.0E b/util/scan/dvb-s/Yamal201-90.0E
new file mode 100644
index 0000000..d0817c5
--- /dev/null
+++ b/util/scan/dvb-s/Yamal201-90.0E
@@ -0,0 +1,48 @@
+# Yamal201 @ 90E
+# freq pol sr fec
+S 10990000 V 2170000 AUTO
+S 10995000 V 4285000 AUTO
+S 11057000 V 26470000 AUTO
+S 11092000 V 26470000 AUTO
+S 11145000 V 22222000 AUTO
+S 11671000 V 18200000 AUTO
+
+# Yamal201 @ 90E C-BAND
+# Generated by Roman Kashcheev
+# Mar 30, 2008
+# freq pol sr fec
+
+# NauTV
+S 3536000 H 2532000 3/4
+# Turkmenistan
+S 3553000 H 20000000 3/4
+# CNL
+S 3577000 H 2626000 3/4
+# Nord TV
+S 3588000 H 4285000 3/4
+# Telekompanija OTV
+S 3600000 H 4285000 3/4
+# Oblastnoe Televidenie
+S 3603000 V 4285000 3/4
+# CNL
+S 3605000 H 2626000 3/4
+# Gascom
+S 3645000 H 28000000 3/4
+# Spas
+S 3674000 H 17500000 3/4
+# TV Gubernia
+S 3725000 H 3200000 3/4
+# Yuzhniy Region
+S 3900000 H 4285000 3/4
+# Rostov TV
+S 3907000 H 4265000 3/4
+# ORTRK 12 Kanal
+S 3912000 H 4295000 3/4
+# O2
+S 3944000 H 15550000 3/4
+# Klub Puteshestviy
+S 3980000 H 38000000 3/4
+# Music Box
+S 4042000 V 8681000 3/4
+# NetService
+S 4084000 V 2500000 3/4
diff --git a/util/scan/dvb-t/at-Offical b/util/scan/dvb-t/at-Offical
new file mode 100644
index 0000000..4a9caf8
--- /dev/null
+++ b/util/scan/dvb-t/at-Offical
@@ -0,0 +1,25 @@
+# Austria, all DVB-T transmitters run by ORS
+# Created from http://www.ors.at/view/ors.php?mid=29
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 490000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 498000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 514000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 522000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 530000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 538000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 546000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 554000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 562000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 578000000 8MHz 3/4 NONE QAM16 8k 1/8 NONE
+T 586000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 594000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 602000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 626000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 634000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 650000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 698000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 722000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 754000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 802000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 858000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/au-sydney_north_shore b/util/scan/dvb-t/au-Adelaide
index 0bb6dd4..3bd3a0f 100644
--- a/util/scan/dvb-t/au-sydney_north_shore
+++ b/util/scan/dvb-t/au-Adelaide
@@ -1,12 +1,12 @@
-# Australia / Sydney / North Shore (aka Artarmon/Gore Hill)
+# Australia / Adelaide / Mt Lofty
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
# ABC
T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Seven
-T 177500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Nine
T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Ten
T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# SBS
-T 571500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 564500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Brisbane b/util/scan/dvb-t/au-Brisbane
new file mode 100644
index 0000000..abf9913
--- /dev/null
+++ b/util/scan/dvb-t/au-Brisbane
@@ -0,0 +1,12 @@
+# Australia / Brisbane (Mt Coot-tha transmitters)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven
+T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine
+T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 585625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Cairns b/util/scan/dvb-t/au-Cairns
new file mode 100644
index 0000000..d9c6208
--- /dev/null
+++ b/util/scan/dvb-t/au-Cairns
@@ -0,0 +1,12 @@
+# Australia / Cairns (Mt Bellenden-Ker transmitters)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC VHF 8
+T 191500000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# SEVEN VHF 11
+T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# WIN VHF 12
+T 226500000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# TEN VHF 6 (Expected Start Date Dec 2006)
+T 177500000 7MHz 3/4 1/2 QAM64 8k 1/16 NONE
+# SBS UHF 29
+T 536500000 7MHz 2/3 2/3 QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Canberra-Black-Mt b/util/scan/dvb-t/au-Canberra-Black-Mt
new file mode 100644
index 0000000..a675100
--- /dev/null
+++ b/util/scan/dvb-t/au-Canberra-Black-Mt
@@ -0,0 +1,12 @@
+# Australia / Canberra / Black Mt
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 205500000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# Prime
+T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# WIN
+T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 177500000 7MHz 3/4 1/2 QAM64 8k 1/16 NONE
+# SBS
+T 543500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Darwin b/util/scan/dvb-t/au-Darwin
index 522bb1d..236d049 100644
--- a/util/scan/dvb-t/au-Darwin
+++ b/util/scan/dvb-t/au-Darwin
@@ -1,5 +1,9 @@
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC (UHF 30)
T 543625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
-T 550500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# Nine (UHF 31)
+T 550500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS (UHF 29)
T 536625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
-T 557625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# Southern Cross (UHF 32)
+T 557625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-GoldCoast b/util/scan/dvb-t/au-GoldCoast
new file mode 100644
index 0000000..64b3969
--- /dev/null
+++ b/util/scan/dvb-t/au-GoldCoast
@@ -0,0 +1,21 @@
+# DVB-T frequencies & modulation for the Gold Coast, Australia (Mt Tamborine)
+# See http://www.dba.org.au/index.asp?sectionID=22&recLocation=Gold+Coast
+# and http://www.dba.org.au/index.asp?sectionID=120
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC (UHF 62)
+T 767500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS (UHF 36)
+T 585500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# Seven (UHF 53)
+T 704500000 7MHz 3/4 NONE QAM64 8k 1/8 NONE
+# NBN (UHF 68)
+T 809500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime (UHF 65)
+T 788500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Southern Cross Ten (UHF 43)
+T 634500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine (UHF 59)
+T 746500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten (UHF 56)
+T 725500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-Hobart b/util/scan/dvb-t/au-Hobart
new file mode 100644
index 0000000..0dac4aa
--- /dev/null
+++ b/util/scan/dvb-t/au-Hobart
@@ -0,0 +1,12 @@
+# Australia / Tasmania / Hobart
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC VHF 8
+T 191625000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# SBS VHF 9a
+T 205500000 7MHz 2/3 2/3 QAM64 8k 1/8 NONE
+# SCT VHF 10
+T 212500000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# WIN VHF 7
+T 184500000 7MHz 3/4 3/4 QAM64 8k 1/8 NONE
+# TDT VHF 11
+T 219500000 7MHz 3/4 3/4 QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Mackay b/util/scan/dvb-t/au-Mackay
new file mode 100644
index 0000000..e7fbfc0
--- /dev/null
+++ b/util/scan/dvb-t/au-Mackay
@@ -0,0 +1,14 @@
+# Australia / Mackay (Mt Blackwood transmitters)
+# aufreq=((UHF channel number)*8+306)
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 212500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven Network
+T 205500000 7MHz 3/4 NONE QAM64 8k 1/8 NONE
+# WIN Digital
+T 578500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Southern Cross Ten
+T 557500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 536500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Melbourne b/util/scan/dvb-t/au-Melbourne
new file mode 100644
index 0000000..6fefbea
--- /dev/null
+++ b/util/scan/dvb-t/au-Melbourne
@@ -0,0 +1,12 @@
+# Australia / Melbourne (Mt Dandenong transmitters)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven
+T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine
+T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 536625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Melbourne-Upwey b/util/scan/dvb-t/au-Melbourne-Upwey
new file mode 100644
index 0000000..2171845
--- /dev/null
+++ b/util/scan/dvb-t/au-Melbourne-Upwey
@@ -0,0 +1,12 @@
+# Australia / Melbourne (Upwey Repeater)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 662500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven
+T 620500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine
+T 641500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 711500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 683500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-MidNorthCoast b/util/scan/dvb-t/au-MidNorthCoast
new file mode 100644
index 0000000..baf3ba5
--- /dev/null
+++ b/util/scan/dvb-t/au-MidNorthCoast
@@ -0,0 +1,22 @@
+# Australia ABC Mid North Coast
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC middle brother
+T 184625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime Middle Brother
+T 198500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# NBN Middle Brother
+T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten Middle Brother
+T 641500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS middle brother
+T 205500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# ABC Moombil
+T 585500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime Moombil
+T 543500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# NBN Moombil
+T 564500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten Moombil
+T 599500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS Moombil
+T 606500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Newcastle b/util/scan/dvb-t/au-Newcastle
new file mode 100644
index 0000000..8fc4552
--- /dev/null
+++ b/util/scan/dvb-t/au-Newcastle
@@ -0,0 +1,12 @@
+# Australia / Newcastle
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 599500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# NBN
+T 585500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime
+T 704500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# ABC
+T 592500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SC10
+T 690500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-Perth b/util/scan/dvb-t/au-Perth
new file mode 100644
index 0000000..1d6778d
--- /dev/null
+++ b/util/scan/dvb-t/au-Perth
@@ -0,0 +1,12 @@
+# Australia / Perth
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven Network
+T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine Network
+T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Network TEN
+T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 536500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Perth_Roleystone b/util/scan/dvb-t/au-Perth_Roleystone
new file mode 100644
index 0000000..496a750
--- /dev/null
+++ b/util/scan/dvb-t/au-Perth_Roleystone
@@ -0,0 +1,12 @@
+# Australia / Perth (Roleystone transmitter)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 704500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# ABC
+T 725500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven
+T 746500000 7MHz 2/3 NONE QAM64 8k 1/16 NONE
+# Nine
+T 767500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 788500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-SpencerGulf b/util/scan/dvb-t/au-SpencerGulf
new file mode 100644
index 0000000..474d66a
--- /dev/null
+++ b/util/scan/dvb-t/au-SpencerGulf
@@ -0,0 +1,8 @@
+# Australia / South Australia / Pt Pirie (THE BLUFF)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 599500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Southern Cross
+T 641500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 620500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-SunshineCoast b/util/scan/dvb-t/au-SunshineCoast
new file mode 100755
index 0000000..32e72e0
--- /dev/null
+++ b/util/scan/dvb-t/au-SunshineCoast
@@ -0,0 +1,12 @@
+# Australia / Sunshine Coast
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 585500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# ABC
+T 767500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven
+T 788500000 7MHz 3/4 NONE QAM64 8k 1/8 NONE
+# Nine
+T 809500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 662625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-Sydney_Kings_Cross b/util/scan/dvb-t/au-Sydney_Kings_Cross
new file mode 100644
index 0000000..ef77870
--- /dev/null
+++ b/util/scan/dvb-t/au-Sydney_Kings_Cross
@@ -0,0 +1,14 @@
+# Australia / Sydney / Kings Cross and North Head
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#
+# ABC UHF30
+T 543500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven UHF48
+T 669500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine UHF33
+T 564500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten UHF45
+T 648500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS UHF34
+T 571500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-Sydney_North_Shore b/util/scan/dvb-t/au-Sydney_North_Shore
new file mode 100644
index 0000000..e175490
--- /dev/null
+++ b/util/scan/dvb-t/au-Sydney_North_Shore
@@ -0,0 +1,16 @@
+# Australia / Sydney / North Shore (aka Artarmon/Gore Hill/Willoughby)
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#
+# ABC VHF12
+T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven VHF6
+T 177500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine VHF8
+T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten VHF11
+T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS UHF34
+T 571500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# D44 UHF35
+T 578500000 7MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/au-Tamworth b/util/scan/dvb-t/au-Tamworth
new file mode 100644
index 0000000..8d28c42
--- /dev/null
+++ b/util/scan/dvb-t/au-Tamworth
@@ -0,0 +1,38 @@
+# Australia / NSW / New England / Tamworth / Mt.Soma
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 690500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# NBN
+T 753500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime
+T 732500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# ABC
+T 711500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SC10
+T 774500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+
+# Australia / NSW / New England / Upper Namoi / Mt.Dowe
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 585500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# NBN
+T 592500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime
+T 205625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# ABC
+T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SC10
+T 613500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+
+# Australia / NSW / Western Districts / Central Western Slopes / Mt. Cenn Cruaich
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 641500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# WIN
+T 648500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime
+T 620500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# ABC
+T 226625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SC10
+T 641500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-Townsville b/util/scan/dvb-t/au-Townsville
new file mode 100644
index 0000000..e411cd4
--- /dev/null
+++ b/util/scan/dvb-t/au-Townsville
@@ -0,0 +1,12 @@
+# Australia / Brisbane (Mt Coot-tha transmitters)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# SBS
+T 592500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# ABC
+T 550500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Seven
+T 599500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Nine
+T 620500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten
+T 585500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-WaggaWagga b/util/scan/dvb-t/au-WaggaWagga
new file mode 100644
index 0000000..cc38f88
--- /dev/null
+++ b/util/scan/dvb-t/au-WaggaWagga
@@ -0,0 +1,12 @@
+# Australia / Wagga Wagga (Mt Ulundra)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# ABC
+T 655500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS
+T 669500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+# Prime
+T 662500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Southern Cross Ten
+T 690500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# WIN
+T 683500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/au-Wollongong b/util/scan/dvb-t/au-Wollongong
new file mode 100644
index 0000000..6fbf7bf
--- /dev/null
+++ b/util/scan/dvb-t/au-Wollongong
@@ -0,0 +1,40 @@
+# Australia / Wollongong
+#
+# Australia modulation params:
+# - http://www.dba.org.au/index.asp?sectionID=120
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#
+# North (Broadcast Site Escarpment Road BROKERS NOSE)
+# - http://www.dba.org.au/index.asp?query=true&sectionID=22&recLocation=Wollongong+%2D+North
+#
+# ABC UHF52
+T 697500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime UHF46
+T 655500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# WIN UHF40
+T 613500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten UHF43
+T 634500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS UHF54
+T 711625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+#
+# Illawarra (Broadcast Australia Digital Television Tower KNIGHTS HILL)
+# - http://www.dba.org.au/index.asp?query=true&sectionID=22&recLocation=Wollongong+%2D+Illawarra
+#
+# ABC UHF51
+T 690500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Prime UHF38
+T 599500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# WIN UHF36
+T 585500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# Ten UHF37
+T 592500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
+# SBS - same as North
+#
+# Stanwell Park (Bald Hill STANWELL TOPS)
+# - http://www.dba.org.au/index.asp?query=true&sectionID=22&recLocation=Wollongong+%2D+Stanwell%20Park
+#
+# ABC, Prime, WIN, Ten are identical to Wollongong / North
+# SBS UHF49
+T 676500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/au-canberra b/util/scan/dvb-t/au-canberra
index 5e71b07..18c0fda 100644
--- a/util/scan/dvb-t/au-canberra
+++ b/util/scan/dvb-t/au-canberra
@@ -3,7 +3,7 @@
# ABC
T 205625000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE
# Seven
-T 177500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 177500000 7MHz 3/4 NONE QAM64 8k 1/8 NONE
# Nine
T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE
# Ten
diff --git a/util/scan/dvb-t/be-Libramont b/util/scan/dvb-t/be-Libramont
new file mode 100644
index 0000000..fb2ae0c
--- /dev/null
+++ b/util/scan/dvb-t/be-Libramont
@@ -0,0 +1,10 @@
+# Libramont - Belgique
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# Canal 7 191.5 MHz M6
+# Canal 24 498.0 MHz RTL-TVI Club-RTL Plug-TV RTL 4,5,7
+# Canal 27 522.0 MHz RTL Lux, den 2ten RTL
+# Canal 56 834.0 MHz RTBF 1,2,3 + radio
+T 191500000 7MHz 1/2 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 1/2 NONE QAM64 8k 1/16 NONE
+T 522000000 8MHz 1/2 NONE QAM64 8k 1/16 NONE
+T 834000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/be-Schoten b/util/scan/dvb-t/be-Schoten
new file mode 100644
index 0000000..d973def
--- /dev/null
+++ b/util/scan/dvb-t/be-Schoten
@@ -0,0 +1,3 @@
+# Schoten-Antwerpen - Belgie
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/be-St_Pieters_Leeuw b/util/scan/dvb-t/be-St_Pieters_Leeuw
new file mode 100644
index 0000000..5e44c3f
--- /dev/null
+++ b/util/scan/dvb-t/be-St_Pieters_Leeuw
@@ -0,0 +1,3 @@
+# St.-Pieters-Leeuw - Belgie
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/be-Tournai b/util/scan/dvb-t/be-Tournai
new file mode 100644
index 0000000..0ed3ca8
--- /dev/null
+++ b/util/scan/dvb-t/be-Tournai
@@ -0,0 +1,3 @@
+# Tournai - Belgique
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/ch-All b/util/scan/dvb-t/ch-All
new file mode 100644
index 0000000..f3f23c3
--- /dev/null
+++ b/util/scan/dvb-t/ch-All
@@ -0,0 +1,29 @@
+# Switzerland, whole country
+# Created from http://www.broadcast.ch/portal.aspx?pid=705
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 514000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 522000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 538000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 554000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 562000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 578000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 594000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 602000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 618000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 626000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 642000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 658000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 666000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 674000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 682000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 690000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 698000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 714000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 722000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 738000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 754000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 762000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 786000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 802000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
+T 826000000 8MHz 5/6 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/ch-Citycable b/util/scan/dvb-t/ch-Citycable
new file mode 100644
index 0000000..3de688e
--- /dev/null
+++ b/util/scan/dvb-t/ch-Citycable
@@ -0,0 +1,14 @@
+# Lausanne - Switzerland (DVB-T on CityCable cable network)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 522000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 554000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 570000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 578000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 586000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 610000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 618000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 626000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 658000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 730000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
+T 746000000 8MHz 7/8 7/8 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/cz-Brno b/util/scan/dvb-t/cz-Brno
new file mode 100644
index 0000000..9bc07f9
--- /dev/null
+++ b/util/scan/dvb-t/cz-Brno
@@ -0,0 +1,4 @@
+# DVB-T Brno (Brno, Czech Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# CRa - Ceske radiokomunikace, TX Barvicova/Hady
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/cz-Domazlice b/util/scan/dvb-t/cz-Domazlice
new file mode 100644
index 0000000..c20f70a
--- /dev/null
+++ b/util/scan/dvb-t/cz-Domazlice
@@ -0,0 +1,3 @@
+# DVB-T Domažlice (Domažlice, Czech Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/cz-Ostrava b/util/scan/dvb-t/cz-Ostrava
new file mode 100644
index 0000000..d2ea69f
--- /dev/null
+++ b/util/scan/dvb-t/cz-Ostrava
@@ -0,0 +1,3 @@
+# DVB-T Ostrava (Ostrava, Czech Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/cz-Praha b/util/scan/dvb-t/cz-Praha
new file mode 100644
index 0000000..d12a8cf
--- /dev/null
+++ b/util/scan/dvb-t/cz-Praha
@@ -0,0 +1,5 @@
+# DVB-T Praha (Prague, Czech Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/16 NONE
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/de-Aachen_Stadt b/util/scan/dvb-t/de-Aachen_Stadt
new file mode 100644
index 0000000..d076b08
--- /dev/null
+++ b/util/scan/dvb-t/de-Aachen_Stadt
@@ -0,0 +1,6 @@
+# DVB-T Aachen-Stadt
+# info from http://www.nrw.ueberallfernsehen.de/fileadmin/downloads/2007-09-14_Programmbelegung_Aachen.pdf
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # ZDF
+T 602000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE # WDR AC
+T 706000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # ARD NRW
diff --git a/util/scan/dvb-t/de-Berlin b/util/scan/dvb-t/de-Berlin
index 416bd11..c975008 100644
--- a/util/scan/dvb-t/de-Berlin
+++ b/util/scan/dvb-t/de-Berlin
@@ -1,5 +1,11 @@
# DVB-T Berlin
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 522000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # ard / rbb
-T 570000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # zdf
-T 658000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # t-systems
+T 177500000 7MHz 3/4 NONE QAM16 8k 1/8 NONE # K5 WDR, SW, BBC, FAB
+T 191500000 7MHz 2/3 NONE QAM16 8k 1/8 NONE # K7 MDR, arte, NDR, ARD-Online-Kanal, ARD-MHP-Data
+T 506000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # K25 RTL, RTL2, Super RTL, VOX
+T 522000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # K27 ARD, RBB, RBB Brd., Phoenix, EinsExtra, ARD-MHP-Data
+T 570000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # K33 ZDF, 3sat, Doku/KiKa
+T 658000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # K44 Sat1, N24, Pro7, Kabel1
+T 754000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # K56 Eurosport, DSF, 9Live, TV.Berlin
+T 778000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # K59 n-tv, Euronews, 33x Radio
+T 618000000 8MHz 1/2 NONE QAM16 8k 1/8 NONE # DVBH Test INT/Service
diff --git a/util/scan/dvb-t/de-Bielefeld b/util/scan/dvb-t/de-Bielefeld
new file mode 100644
index 0000000..ee12dfe
--- /dev/null
+++ b/util/scan/dvb-t/de-Bielefeld
@@ -0,0 +1,7 @@
+# DVB-T Ostwestfalen
+# http://www.nrw.ueberallfernsehen.de/fileadmin/downloads/DVB-T_P3.1_OWL.pdf
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 554000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 570000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Braunschweig b/util/scan/dvb-t/de-Braunschweig
new file mode 100644
index 0000000..8dd39e2
--- /dev/null
+++ b/util/scan/dvb-t/de-Braunschweig
@@ -0,0 +1,7 @@
+# DVB-T Braunschweig -- info from http://www.skyplus.seyen.de/DVB-T.html
+T 198500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 490000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 498000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 594000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 658000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 786000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Bremen b/util/scan/dvb-t/de-Bremen
new file mode 100644
index 0000000..bc05505
--- /dev/null
+++ b/util/scan/dvb-t/de-Bremen
@@ -0,0 +1,9 @@
+# DVB-T Bremen/Unterweser
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 AUTO QAM16 8k 1/4 NONE
+T 538000000 8MHz 2/3 1/2 QAM16 8k 1/4 NONE
+T 562000000 8MHz 2/3 2/3 QAM16 8k 1/4 NONE
+T 642000000 8MHz 2/3 2/3 QAM16 8k 1/4 NONE
+T 666000000 8MHz 2/3 2/3 QAM16 8k 1/4 NONE
+T 698000000 8MHz 2/3 2/3 QAM16 8k 1/4 NONE
+T 746000000 8MHz 2/3 2/3 QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Brocken_Magdeburg b/util/scan/dvb-t/de-Brocken_Magdeburg
new file mode 100644
index 0000000..e17988b
--- /dev/null
+++ b/util/scan/dvb-t/de-Brocken_Magdeburg
@@ -0,0 +1,7 @@
+# DVB-T Brocken/Magdeburg (Germany)
+# Generated by Tobias Stoeber <mail@tobias-stoeber.de>
+# info from: http://www.dvbt-mitteldeutschland.de/index.php?content=Programme&menu=Technische&region=MD
+
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # CH29: ARD Das Erste, EinsFestival, arte, Phoenix (TSMB/MDR1.1)
+T 546000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH30: 3sat, ZDFDoku/KIKA, ZDF, ZDFInfo (ZDF)
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # CH34: MDR S-ANHALT, rbb Brandenburg, WDR Koeln, NDR FS NDS (TSMB/MDR2.2)
diff --git a/util/scan/dvb-t/de-Chemnitz b/util/scan/dvb-t/de-Chemnitz
new file mode 100644
index 0000000..c5ea0f8
--- /dev/null
+++ b/util/scan/dvb-t/de-Chemnitz
@@ -0,0 +1,5 @@
+# DVB-T Chemnitz
+# T freq bw fec_hi fec lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # ard, arte, phoenix, einsfest
+T 482000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # zdf, 3sat, zdf-doku,/kika
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # mdr, rbb, wdr, br
diff --git a/util/scan/dvb-t/de-Dresden b/util/scan/dvb-t/de-Dresden
new file mode 100644
index 0000000..2945846
--- /dev/null
+++ b/util/scan/dvb-t/de-Dresden
@@ -0,0 +1,5 @@
+# DVB-T Dresden
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # Kanal 29, mdr, rbb, wdr, br
+T 594000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 36, zdf, 3sat, kika, none
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # Kanal 39, ard, arte, phoenix, 1festival
diff --git a/util/scan/dvb-t/de-Erfurt-Weimar b/util/scan/dvb-t/de-Erfurt-Weimar
new file mode 100644
index 0000000..f266ac6
--- /dev/null
+++ b/util/scan/dvb-t/de-Erfurt-Weimar
@@ -0,0 +1,5 @@
+# DVB-T Erfurt-Weimar
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 21, ARD, arte, Phoenix, Eins festival
+T 522000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # Kanal 27, MDR Thüringen, rbb, WDR, hr
+T 706000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # Kanal 50, ZDF, ZDF info / 3sat, KiKA / ZDF doku, MHP
diff --git a/util/scan/dvb-t/de-Frankfurt b/util/scan/dvb-t/de-Frankfurt
new file mode 100644
index 0000000..5dc3418
--- /dev/null
+++ b/util/scan/dvb-t/de-Frankfurt
@@ -0,0 +1,41 @@
+###########################################
+# DVB-T, Deutschland, Rhein-Main Gebiet
+###########################################
+
+# Start der Ausstrahlung: ARD Multiplex 2 und ZDF Multiplex ab 04.10.2004.
+# ARD Multiplex 1 sowie Private Multiplex 1 bis 3 am 06.12.2004.
+
+# ARD Multiplex 2 Kanal 57 wurde am 03.12.2007 auf Kanal 37 verschoben
+
+# Alle DVB-T Sender im Rhein-Main Gebiet senden vertikal polarisiert
+
+# Sender auf dem grossen Feldberg und FFM-Fernmeldeturm sind Rundstrahler,
+# Hohe Wurzel ist Richtstrahler
+
+# Kanaele 5 bis 10 liegen im "VHF"-Band, 21 bis 69 im "UHF"-Band, d.h.,
+# nur ARD Multiplex 1 wird im VHF-Band gesendet.
+
+# Nettodatenrate 13.06 MBit/s fuer ARD Multiplex 1, 13.27 MBit/s fuer alle anderen
+
+
+##################################################################################
+#T freq bw coderate_HP coderate_LP modulation transmode guard-int hierarchy
+#--------------------------------------------------------------------------------
+
+# Kanal 8, ARD Multiplex 1, Grosser Feldberg 10kW, Hohe Wurzel 20kW, FFM-Turm 10kW
+T 198500000 7MHz 2/3 NONE QAM16 8k 1/4 NONE
+
+# Kanal 22, ZDF Multiplex, Grosser Feldberg 50kW, Hohe Wurzel 100kW, FFM-Turm 50kW
+T 482000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+
+# Kanal 34, Private Multiplex 1, Grosser Feldberg 50kW, Hohe Wurzel 100kW, FFM-Turm 50kW
+T 578000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+
+# Kanal 37, ARD Multiplex 2, Grosser Feldberg 50kW, Hohe Wurzel 100kW, FFM-Turm 50kW
+T 602000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+
+# Kanal 54, Private Multiplex 2, Grosser Feldberg 50kW, Hohe Wurzel 100kW, FFM-Turm 50kW
+T 738000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+
+# Kanal 64, Private Multiplex 3, Grosser Feldberg 50kW, Hohe Wurzel 100kW, FFM-Turm 50kW
+T 818000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Freiburg b/util/scan/dvb-t/de-Freiburg
new file mode 100644
index 0000000..5066a21
--- /dev/null
+++ b/util/scan/dvb-t/de-Freiburg
@@ -0,0 +1,5 @@
+# DVB-T Freiburg M/V
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 618000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 722000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-HalleSaale b/util/scan/dvb-t/de-HalleSaale
new file mode 100644
index 0000000..19b94e7
--- /dev/null
+++ b/util/scan/dvb-t/de-HalleSaale
@@ -0,0 +1,6 @@
+# DVB-T Halle/Saale (Germany)
+# Generated by Albrecht Lohoefener <albrechtloh@gmx.de> http://www.albrechtloh.de
+
+T 642000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH1:ZDF CH2:ZDFinfo/3sat CH3:ZDFDoku/KiKa
+T 586000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH1:BR CH2:MDR CH3:rbb CH4:NDR
+T 482000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH1:arte CH2:Phoenix CH3:EinsFestival CH4:ARD
diff --git a/util/scan/dvb-t/de-Hamburg b/util/scan/dvb-t/de-Hamburg
new file mode 100644
index 0000000..a3658e5
--- /dev/null
+++ b/util/scan/dvb-t/de-Hamburg
@@ -0,0 +1,15 @@
+# DVB-T Hamburg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 205500000 7MHz 3/4 NONE QAM16 8k 1/8 NONE # CH09: NDR, WDR, MDR, Bayrisches Fernsehen
+T 490000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH23: ZDF, Info/3sat, Doku/KiKa
+T 498000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 514000000 8MHz 3/4 AUTO QAM16 8k 1/4 NONE #ARD, MDR S-Anhalt, NDR MV, NDR SH, rbb Berlin
+T 530000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 546000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH30: Sat.1, N24, ProSieben, KABEL1
+T 570000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH33: Das Erste Hamburg, Eins Extra, arte, Phoenix
+T 602000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 626000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH40: RTL Television, RTL2, Super RTL, VOX
+T 674000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH53: HH1, Eurosport, Terra Nova, Neun Live
+T 738000000 8MHz 3/4 AUTO QAM16 8k 1/4 NONE #ZDF, Doku/KiKa, Info/3sat
+T 754000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # CH56: NDR, MDR, WDR, hr
+T 786000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Hannover b/util/scan/dvb-t/de-Hannover
new file mode 100644
index 0000000..af838a0
--- /dev/null
+++ b/util/scan/dvb-t/de-Hannover
@@ -0,0 +1,7 @@
+# DVB-T Hannover -- info from http://www.skyplus.seyen.de/DVB-T.html
+T 198500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 490000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 498000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 530000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 594000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 658000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Kassel b/util/scan/dvb-t/de-Kassel
new file mode 100644
index 0000000..09958ab
--- /dev/null
+++ b/util/scan/dvb-t/de-Kassel
@@ -0,0 +1,31 @@
+# DVB-T, Germany, Nordhessen, Region Kassel
+###########################################
+
+# broadcasting started 29.06.2006
+
+# broadcasting on 3 frequencies: 562KHz, 642KHz, 746KHz
+
+# broacasting stations: Hoher Meissner, Habichtswald
+
+# available programs:-------------
+# ARD
+# ZDF
+# arte/EinsFestival
+# 3sat
+# HR
+# NDR
+# MDR
+# WDR
+# Phoenix
+# Doku/KiKa
+
+##################################################################################
+
+# ARD, HR, arte/EinsFestival
+T 562000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
+
+# ZDF, 3sat, Doku/KiKa
+T 642000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+
+# Phoenix, NDR, MDR, WDR
+T 746000000 8MHz 3/4 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Kiel b/util/scan/dvb-t/de-Kiel
new file mode 100644
index 0000000..da13fb4
--- /dev/null
+++ b/util/scan/dvb-t/de-Kiel
@@ -0,0 +1,8 @@
+# DVB-T Kiel
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 21, ZDF, ZDFInfokanal/3Sat, KI.KA/ ZDFdokukanal, MHP: ZDFdigitext
+T 586000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 35, Kabel 1, N24, ProSieben, SAT.1 Fernsehen
+T 618000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 39, NDR, WDR, mdr, Bayerisches Fernsehen
+T 666000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 45, RTL Television, RTL II, Super RTL, VOX
+T 682000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 47, ARD, Phoenix, arte, Eins Extra
+T 762000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Kanal 57, EuroSport, 9Live, TELE 5
diff --git a/util/scan/dvb-t/de-Koeln-Bonn b/util/scan/dvb-t/de-Koeln-Bonn
new file mode 100644
index 0000000..78aa56a
--- /dev/null
+++ b/util/scan/dvb-t/de-Koeln-Bonn
@@ -0,0 +1,9 @@
+# DVB-T NRW/Bonn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 538000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 594000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 650000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 698000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 706000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 826000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Leipzig b/util/scan/dvb-t/de-Leipzig
new file mode 100644
index 0000000..870ae15
--- /dev/null
+++ b/util/scan/dvb-t/de-Leipzig
@@ -0,0 +1,5 @@
+# DVB-T Leipzig (Germany)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 205500000 7MHz 2/3 NONE QAM64 8k 1/16 NONE # mdr rbb wdr brs
+T 482000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # zdf kika 3sat
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # ard einsfestival arte phoenix
diff --git a/util/scan/dvb-t/de-Loerrach b/util/scan/dvb-t/de-Loerrach
new file mode 100644
index 0000000..705a71f
--- /dev/null
+++ b/util/scan/dvb-t/de-Loerrach
@@ -0,0 +1,19 @@
+# DVB-T transmitter of Lörrach - Germany
+# signal DVB-T transmis depuis l'émetteur de Lörrach - Allemagne
+#
+# Fichier réalisé par :
+# IUT COLMAR DEPARTEMENT RESEAUX ET TELECOMMUNICATIONS
+# Novembre 2007
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# Chaînes allemandes
+
+# ch 33 : 3sat, Doku/KiKa, ZDF, ZDFinfokanal
+T 570000000 8MHz AUTO NONE QAM16 8k AUTO NONE
+
+# ch 39 : SWR Fernsehen BW, hr-fernsehen, WDR Fernsehen et Bayerisches FS
+T 618000000 8MHz AUTO NONE QAM16 8k AUTO NONE
+
+# ch 52 : Das Erste, arte (Allemagne), Phoenix et EinsPlus
+T 722000000 8MHz AUTO NONE QAM16 8k AUTO NONE
diff --git a/util/scan/dvb-t/de-Luebeck b/util/scan/dvb-t/de-Luebeck
new file mode 100644
index 0000000..5779502
--- /dev/null
+++ b/util/scan/dvb-t/de-Luebeck
@@ -0,0 +1,7 @@
+# DVB-T Lübeck
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 530000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 546000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 570000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 626000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
diff --git a/util/scan/dvb-t/de-Muenchen b/util/scan/dvb-t/de-Muenchen
new file mode 100644
index 0000000..9fee24b
--- /dev/null
+++ b/util/scan/dvb-t/de-Muenchen
@@ -0,0 +1,10 @@
+# DVB-T Muenchen/Bayern
+# by Christoph Anton Mitterer (cam@mathematica.scientia.net)
+# http://christoph.anton.mitterer.name/
+
+T 212500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE
+T 578000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 586000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 690000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 754000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 834000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Nuernberg b/util/scan/dvb-t/de-Nuernberg
new file mode 100644
index 0000000..39eb56f
--- /dev/null
+++ b/util/scan/dvb-t/de-Nuernberg
@@ -0,0 +1,8 @@
+# DVB-T Nuernberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 184500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE # ard
+T 578000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # zdf
+T 626000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # prosieben
+T 778000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # br
+T 786000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # franken
+T 834000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # rtl
diff --git a/util/scan/dvb-t/de-Osnabrueck b/util/scan/dvb-t/de-Osnabrueck
new file mode 100644
index 0000000..9bbb58e
--- /dev/null
+++ b/util/scan/dvb-t/de-Osnabrueck
@@ -0,0 +1,5 @@
+# DVB-T Osnabrueck/Lingen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 AUTO QAM16 8k 1/4 NONE
+T 778000000 8MHz 2/3 AUTO QAM16 8k 1/4 NONE
+T 602000000 8MHz 2/3 AUTO QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Ostbayern b/util/scan/dvb-t/de-Ostbayern
new file mode 100644
index 0000000..2c5bdf5
--- /dev/null
+++ b/util/scan/dvb-t/de-Ostbayern
@@ -0,0 +1,11 @@
+# DVB-T Ostbayern/Bayern
+# for the Region around Regensburg, Straubing, Cham, Zwiesel, Freyung, Passau, Pfarrkirchen
+# Thorsten Pinz (tom_p at gmx.de)
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 191500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE #K07, ARD (Hohe Linie, Hoher Bogen, Brotjackelriegel)
+T 522000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K27, BR (Pfarrkirchen, Brotjackelriegel)
+T 530000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K28, BR (Hohe Linie, Hoher Bogen)
+T 570000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K33, ZDF (Hoher Bogen, Brotjackelriegel, Pfarrkirchen)
+T 626000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K40, ARD (Pfarrkirchen)
+T 730000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K53, ZDF (Hohe Linie)
diff --git a/util/scan/dvb-t/de-Ravensburg b/util/scan/dvb-t/de-Ravensburg
new file mode 100644
index 0000000..9482448
--- /dev/null
+++ b/util/scan/dvb-t/de-Ravensburg
@@ -0,0 +1,8 @@
+# DVB-T Ravensburg/Bodensee
+# T freq bw fec_hi fec_lo mod transmission-mode guard-i
+T 474000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 498000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 578000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 482000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 626000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 650000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Rostock b/util/scan/dvb-t/de-Rostock
new file mode 100644
index 0000000..8e2dc75
--- /dev/null
+++ b/util/scan/dvb-t/de-Rostock
@@ -0,0 +1,4 @@
+# DVB-T Rostock
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 1/2 QAM16 8k 1/4 NONE # ARD / NDR
+T 674000000 8MHz 2/3 1/2 QAM16 8k 1/4 NONE # ZDF
diff --git a/util/scan/dvb-t/de-Ruhrgebiet b/util/scan/dvb-t/de-Ruhrgebiet
new file mode 100644
index 0000000..0f3821c
--- /dev/null
+++ b/util/scan/dvb-t/de-Ruhrgebiet
@@ -0,0 +1,19 @@
+# DVB-T Düsseldorf/Ruhrgebiet
+# Not everyone in this area will be able to tune on the last
+# 3 frequencies, as they are not broadcasted in the whole area.
+# See http://nrw.ueberallfernsehen.de/fileadmin/images/programmbelegung_ddrf.gif
+# for details on regional availability.
+#
+# Updated to the new settings, I do not know how long this file has not been updatet,
+# but now it's done and I hope everyone will now be able to recieve ARD, arte, Phoenix
+# and Eins-Festival out of the box now.
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Düsseldorf, Wesel, Essen, Langenberg, Dortmund
+T 586000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Düsseldorf, Wesel, Essen, Langenberg, Dortmund
+T 722000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Düsseldorf, Wesel, Essen, Langenberg, Dortmund
+T 746000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Düsseldorf, Wesel, Essen, Langenberg, Dortmund
+T 690000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Düsseldorf, Wesel, Essen, Langenberg, Dortmund, Kleve
+T 506000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # Langenberg, Dortmund
+T 674000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE # Düsseldorf, Wesel, Langenberg
+T 778000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE # Essen, Gelsenkirchen, Scholven
diff --git a/util/scan/dvb-t/de-Schwerin b/util/scan/dvb-t/de-Schwerin
new file mode 100644
index 0000000..9f0ffd8
--- /dev/null
+++ b/util/scan/dvb-t/de-Schwerin
@@ -0,0 +1,4 @@
+# DVB-T Schwerin M/V
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 3/4 AUTO QAM16 8k 1/4 NONE #ARD, MDR S-Anhalt, NDR MV, NDR SH, rbb Berlin
+T 738000000 8MHz 3/4 AUTO QAM16 8k 1/4 NONE #ZDF, Doku/KiKa, Info/3sat
diff --git a/util/scan/dvb-t/de-Stuttgart b/util/scan/dvb-t/de-Stuttgart
new file mode 100644
index 0000000..ea2676b
--- /dev/null
+++ b/util/scan/dvb-t/de-Stuttgart
@@ -0,0 +1,6 @@
+# DVB-T Stuttgart
+# by Joerg Marhenke (joerg.marhenke@uni-ulm.de)
+
+T 522000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 706000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 730000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/de-Wuerzburg b/util/scan/dvb-t/de-Wuerzburg
new file mode 100644
index 0000000..ff7e77b
--- /dev/null
+++ b/util/scan/dvb-t/de-Wuerzburg
@@ -0,0 +1,7 @@
+# DVB-T Wuerzburg/Bayern
+#Thorsten Becker (thorsten.becker@cloupage.de)
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 212500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE #K10, ARD
+T 506000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K25, ZDF
+T 666000000 8MHz 2/3 NONE QAM16 8k 1/4 NONE #K45, BR
diff --git a/util/scan/dvb-t/dk-All b/util/scan/dvb-t/dk-All
new file mode 100644
index 0000000..135c043
--- /dev/null
+++ b/util/scan/dvb-t/dk-All
@@ -0,0 +1,16 @@
+# Denmark, whole country
+# Created from http://www.digi-tv.dk/Indhold_og_tilbud/frekvenser.asp
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/es-Albacete b/util/scan/dvb-t/es-Albacete
new file mode 100644
index 0000000..ea67c6f
--- /dev/null
+++ b/util/scan/dvb-t/es-Albacete
@@ -0,0 +1,8 @@
+# Spain, Albacete
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 59: La Primera, La 2, Canal 24H, Clan/TVE 50, RNE1, RNE Clásica, RNE 3
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: CLMTV
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Veo, Veo 2, Net TV, Teledeporte
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: Cuatro, CNN+, 40 Latino, La Sexta 1
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Telecinco, Telecinco Sport, Telecinco Estrellas, Fly Music
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, Antena Neox, Antena Nova, La Sexta 2
diff --git a/util/scan/dvb-t/es-Alfabia b/util/scan/dvb-t/es-Alfabia
new file mode 100644
index 0000000..dc2956c
--- /dev/null
+++ b/util/scan/dvb-t/es-Alfabia
@@ -0,0 +1,8 @@
+# DVB-T Alfabia, Mallorca, Balearic Islands, Spain.
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 810000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C.63: 24h, 50 aniv., ClanTV, La 2, TVE1; RNE 1, RNE 3, RNE C; Digitext, EPG, Lanzadera.
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C.65: IB3, Aprenda Ingles TV
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C.66: NetTV, Teledeporte, VeoTV1, VeoTV2.
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C.67: 40 Latino TV, CNN+, Cuatro, La Sexta 1.
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C.68: Fly Music, Tele 5, Tele 5 Estrellas, Tele 5 Sport.
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C.69: Antena 3, La Sexta 2, Neox, Nova.
diff --git a/util/scan/dvb-t/es-Alicante b/util/scan/dvb-t/es-Alicante
new file mode 100644
index 0000000..a804b38
--- /dev/null
+++ b/util/scan/dvb-t/es-Alicante
@@ -0,0 +1,9 @@
+# DVB-T Alicante, Spain
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 55: TV3, K33/33, 3/24, Canal 300
+T 770000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 58: La Primera, La 2, Canal 24H, Clan/TVE 50, RNE1, RNE Clásica, RNE 3
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: Telemadrid, La Otra, Onda 6
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Veo, Veo 2, Net TV, Teledeporte
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: Cuatro, CNN+, 40 Latino, La Sexta 1
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Telecinco, Telecinco Sport, Telecinco Estrellas, Fly Music
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, Antena Neox, Antena Nova, La Sexta 2
diff --git a/util/scan/dvb-t/es-Alpicat b/util/scan/dvb-t/es-Alpicat
new file mode 100644
index 0000000..ffdf7a3
--- /dev/null
+++ b/util/scan/dvb-t/es-Alpicat
@@ -0,0 +1,8 @@
+# DVB-T Alpicat (Lleida)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c58: TV3, K3/33, 3/24, 300, 3i
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c64: TVE1, TVE2, Teledeporte, C24h
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c66: TVE ClanTV, TVE 50a, Veo1, Veo2, Net
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c67: Cuatro, 40Latino, CNN+, LaSexta 1
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c68: T5, T5 Sports, T5 Estrellas, Net Fly Music
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c69: Antena3, Antena.Neox, Antena.Nova, La Sexta 2
diff --git a/util/scan/dvb-t/es-Asturias b/util/scan/dvb-t/es-Asturias
new file mode 100644
index 0000000..f5069df
--- /dev/null
+++ b/util/scan/dvb-t/es-Asturias
@@ -0,0 +1,8 @@
+# DVB-T Asturias
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TPA TPA2
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TVE 1, TVE 2, 24H TVE, CLAN/50 TVE, RNE1, RNE CLASICA, RNE3
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TELEDEPORTE, VEO TV, VEO 2, NET TV
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # CUATRO, CNN+, 40 LATINO, LA SEXTA 1
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TELECINCO, T5 ESTRELLAS, T5 SPORT, FLYMUSIC
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # ANTENA 3, ANTENA.NEOX, ANTENA.NOVA, LA SEXTA 2
diff --git a/util/scan/dvb-t/es-Bilbao b/util/scan/dvb-t/es-Bilbao
new file mode 100644
index 0000000..6d1b18a
--- /dev/null
+++ b/util/scan/dvb-t/es-Bilbao
@@ -0,0 +1,6 @@
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: CNN+. Cuatro, La Sexta, 40 latino TV
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, La Sexta 2, Neo, Nova, Telehit, Onda Cero, Europa FM, Onda Melodia
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: La Primera, La 2, Canal 24H, Clan/TVE 50, RNE1, RNE Clásica, RNE 3
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Veo, Veo 2, Net TV, Teledeporte
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Telecinco, Telecinco Sport, Telecinco Estrellas, Fly Music
+T 794000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 61: ETB1, ETB2, ETB-Sat, Canal Vasco, Euskadi Irratia, Radio Euskadi, Euskadi Gastea, Radio EITB
diff --git a/util/scan/dvb-t/es-Carceres b/util/scan/dvb-t/es-Carceres
new file mode 100644
index 0000000..6755954
--- /dev/null
+++ b/util/scan/dvb-t/es-Carceres
@@ -0,0 +1,10 @@
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 39: 8Madrid, TMT-Popular TV, Kiss TV, Intereconomía TV
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 50: EsMadrid TV, Ver-t, EM2, Libertad Digital TV
+T 770000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 58: La Primera, La 2, Canal 24H, Clan/TVE 50, RNE1, RNE Clásica, RNE 3
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: Telemadrid, La Otra, Onda 6
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Veo, Veo 2, Net TV, Teledeporte
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: Cuatro, CNN+, 40 Latino, La Sexta 1
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Telecinco, Telecinco Sport, Telecinco Estrellas, Fly Music
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, Antena Neox, Antena Nova, La Sexta 2
+T 794000000 8Mhz 2/3 1/2 QAM64 8K 1/4 NONE # Canal 61: Canal Extremadura, Extremadura Television
diff --git a/util/scan/dvb-t/es-Collserola b/util/scan/dvb-t/es-Collserola
index 04ffe54..bec8c8b 100644
--- a/util/scan/dvb-t/es-Collserola
+++ b/util/scan/dvb-t/es-Collserola
@@ -1,6 +1,10 @@
# DVB-T Collserola (Barcelona)
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 650000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE # C43: tvc
-T 794000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C61: tve, t5, a3, c+
-T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C66: veotv, nettv
-
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c26: BTV
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c33: CityTV
+T 794000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c61: TV3, K3/33, 3/24, 300
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c64: TVE1, TVE2, TVE 24H, Clan/TVE 50 Años, RNE1, RNEC, RNE3
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c66: Veo TV, Veo2, Net TV, Teledeporte
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c67: Cuatro, CNN+, 40 Latino, La Sexta1
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c68: Telecino, T5 Sport, T5 Estrellas, Fly Music
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #c69: Antena 3, Antena.Neox, Antena.Nova, La Sexta2
diff --git a/util/scan/dvb-t/es-Donostia b/util/scan/dvb-t/es-Donostia
new file mode 100644
index 0000000..7ea5f50
--- /dev/null
+++ b/util/scan/dvb-t/es-Donostia
@@ -0,0 +1,14 @@
+# The channels with 1/32 guard-interval are French and should be perfectly visible
+# here. However I have only managed to get a lock for the channel 57 of the French ones.
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 32: CNN+, Cuatro, La Sexta 1, 40 Latino TV, EPG Soge V2 5
+T 626000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 40: Antena 3, Antena.Neox, Antena.Nova, Telehit, Onda Cero, Europa FM, Onda Melodia, A3Lanzadera, A3Portal, EPGA3, A3Ticker
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # Canal 42: Direct8, TMC, BFM, iTele, Europe2TV, Gulli
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # Canal 49: M6, W9, NT1
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # Canal 51: Canal+, Canal+ Cinema, Canal+ Sport
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # Canal 57: TF1, NRJ12, Eurosport, TPS Star, LCI
+T 786000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 60: ETB1, ETB2, ETB-Sat, Canal Vasco, Euskadi Irratia, Radio Euskadi, Euskadi Gaztea, Radio Etb, TGov, Eguraldi
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: TVE1, TVE2, 24H TVE, Clan/TVE 50 anos, RNE, RNEC, RNE3, Lanzadera, EPG, Digitext, Meteo, Bolsa, Trafico, Empleat
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # Canal 65: France 2, France 3, France 4, France 5, Arte, LCP
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Net TV, Teledeporte, Veo TV1, Veo TV2, Lanzadera, EPG, Digitext, Meteo, Bolsa, Trafico, Empleat
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Fly Music, Tele 5, Tele 5 Estrellas, Tele 5 Sport
diff --git a/util/scan/dvb-t/es-Las_Palmas b/util/scan/dvb-t/es-Las_Palmas
new file mode 100644
index 0000000..0475937
--- /dev/null
+++ b/util/scan/dvb-t/es-Las_Palmas
@@ -0,0 +1,8 @@
+# Funciona correctamente en Las Palmas de Gran Canaria (24-4-2007)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 786000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 60: TVE1, TVE2, 24H TVE, Clan/TVE, RNE, RNEC, RNE3, Lanzadera, EPG, Digitext, Meteo, Bolsa, Trafico, Empleat
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # Canal 65: TV C, TV C2
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Net TV, Teledeporte, Veo TV1, SETenVeo, Radio Intereconomía Lanzadera, EPG, Digitext, Meteo, Bolsa, Trafico, Empleat
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: CNN+, Cuatro, La Sexta 1, 40 Latino TV, EPG Soge V2 5
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Fly Music, Punto Radio, Tele 5, Tele 5 Estrellas, Tele 5 Sport
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, Antena.Neox, Antena.Nova, Telehit, Onda Cero, Europa FM, Onda Melodia, A3Lanzadera, A3Portal, EPGA3, A3Ticker
diff --git a/util/scan/dvb-t/es-Lugo b/util/scan/dvb-t/es-Lugo
new file mode 100644
index 0000000..7b76544
--- /dev/null
+++ b/util/scan/dvb-t/es-Lugo
@@ -0,0 +1,9 @@
+# DVB-T Lugo (Centro emisor Paramo) - Rev. 1.2 - 11.12.05
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TVE 1, TVE 2, 24H TVE, CLAN/50 TVE, RNE1, RNE CLASICA, RNE3
+T 810000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TVG, GALICIA TV AMERICA, RADIO GALEGA, R.GALEGA MUSICA, SON GALICIA RADIO, PROBAS RETEGAL
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TELEDEPORTE, VEO TV, VEO 2, NET TV
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # CUATRO, CNN+, 40 LATINO, LA SEXTA 1
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TELECINCO, T5 ESTRELLAS, T5 SPORT, FLYMUSIC
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # ANTENA 3, ANTENA.NEOX, ANTENA.NOVA, LA SEXTA 2
diff --git a/util/scan/dvb-t/es-Madrid b/util/scan/dvb-t/es-Madrid
new file mode 100644
index 0000000..5834bd1
--- /dev/null
+++ b/util/scan/dvb-t/es-Madrid
@@ -0,0 +1,8 @@
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 39: 8Madrid, TMT-Popular TV, Kiss TV, Intereconomía TV
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 50: EsMadrid TV, Ver-t, EM2, Libertad Digital TV
+T 770000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 58: La Primera, La 2, Canal 24H, Clan/TVE 50, RNE1, RNE Clásica, RNE 3
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: Telemadrid, La Otra, Onda 6
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Veo, Veo 2, Net TV, Teledeporte
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: Cuatro, CNN+, 40 Latino, La Sexta 1
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Telecinco, Telecinco Sport, Telecinco Estrellas, Fly Music
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, Antena Neox, Antena Nova, La Sexta 2
diff --git a/util/scan/dvb-t/es-Malaga b/util/scan/dvb-t/es-Malaga
new file mode 100644
index 0000000..7da1610
--- /dev/null
+++ b/util/scan/dvb-t/es-Malaga
@@ -0,0 +1,9 @@
+# DVB-T Malaga (Andalucia) by Pedro Leon 4 Mayo 2007
+# T freq bw fec_hi fec_lo mod transm-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # C57 La Primera, La 2, Canal 24H, Clan/TVE 50, RNE1, RNE Clásica, RNE 3
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # C63 Canal Sur, Canal 2 Andalucia
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # C66 TELEDEPORTE, VEO, *Canal Ingenieria, SETenVEO, Tienda en VEO, NET TV, Radio Intereconomia
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # C67 CUATRO, CNN+, 40 LATINO, laSexta
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # C68 Telecinco, T5 Estrellas, T5 Sport, FLYMUSIC, PUNTO RADIO
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # C69 ANTENA 3, ANTENA.NEOX, ANTENA.NOVA, *tvtv DIGITAL, ONDA CERO, EUROPA FM, ONDA MELODIA, Telehit
+# * Canales de datos o MHT
diff --git a/util/scan/dvb-t/es-Mussara b/util/scan/dvb-t/es-Mussara
new file mode 100644
index 0000000..9feb073
--- /dev/null
+++ b/util/scan/dvb-t/es-Mussara
@@ -0,0 +1,8 @@
+# DVB-T La Mussara (Reus-Tarragona)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c59: TV3, K3/33, 3/24, 300, 3i
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c64: TVE1, TVE2, Teledeporte, C24h
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c66: TVE ClanTV, TVE 50a, Veo1, Veo2, Net
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c67: Cuatro, 40Latino, CNN+, LaSexta 1
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c68: T5, T5 Sports, T5 Estrellas, Net Fly Music
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # c69: Antena3, Antena.Neox, Antena.Nova, La Sexta 2
diff --git a/util/scan/dvb-t/es-Rocacorba b/util/scan/dvb-t/es-Rocacorba
new file mode 100644
index 0000000..8eebbbf
--- /dev/null
+++ b/util/scan/dvb-t/es-Rocacorba
@@ -0,0 +1,6 @@
+# DVB-T Rocacorba (Girona)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TVE 1, TVE 2, ANTENA 3, TELECINCO, CUATRO
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # TV3, K3/33, 3XL.NET, 3/24, CANAL PILOT
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # SERVICIO PRUEBAS CANAL 67
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE #
diff --git a/util/scan/dvb-t/es-Santander b/util/scan/dvb-t/es-Santander
new file mode 100644
index 0000000..94326d4
--- /dev/null
+++ b/util/scan/dvb-t/es-Santander
@@ -0,0 +1,7 @@
+# file automatically generated by w_scan
+# (http://wirbel.htpc-forum.de/w_scan/index2.html)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 2/3 QAM64 8k 1/4 NONE
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/es-Sevilla b/util/scan/dvb-t/es-Sevilla
new file mode 100644
index 0000000..1011dec
--- /dev/null
+++ b/util/scan/dvb-t/es-Sevilla
@@ -0,0 +1,8 @@
+# DVB-T Sevilla (Andalucia) by x2 15 Agosto 2006
+# T freq bw fec_hi fec_lo mod transm-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C57
+T 794000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C61
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C66
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C67
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C68
+T 858000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE # C69
diff --git a/util/scan/dvb-t/es-Valladolid b/util/scan/dvb-t/es-Valladolid
new file mode 100644
index 0000000..25cb74a
--- /dev/null
+++ b/util/scan/dvb-t/es-Valladolid
@@ -0,0 +1,7 @@
+# DVB-T Valladolid
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 57: Clan TVE, 24H TVE, La 2, TVE 1, RNE1, RNE3, RNC
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: Veo, Veo 2, Net TV, Teledeporte
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: Cuatro, CNN+, 40 Latino, La Sexta 1
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: Telecinco, Telecinco Sport, Telecinco Estrellas, Fly Music
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: Antena 3, Antena Neox, Antena Nova, La Sexta 2
diff --git a/util/scan/dvb-t/es-Vilamarxant b/util/scan/dvb-t/es-Vilamarxant
new file mode 100644
index 0000000..a3867c1
--- /dev/null
+++ b/util/scan/dvb-t/es-Vilamarxant
@@ -0,0 +1,4 @@
+# DVB-T Vilamarxant, Valencia, C. Valenciana, Spain.
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/es-Zaragoza b/util/scan/dvb-t/es-Zaragoza
new file mode 100644
index 0000000..95588b6
--- /dev/null
+++ b/util/scan/dvb-t/es-Zaragoza
@@ -0,0 +1,7 @@
+# DVB-T Zaragoza (Aragón) [Spain] [es-Zaragoza]
+# Generated by Víctor Martínez Romanos <vmromanos@gmail.com>
+T 794000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 63: TVE 1, TVE 2, 24H, CLAN/50, RNE1, RNEC, RNE3
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 66: TELEDEPORTE, VEO TV, VEO 2, NET TV
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 67: CUATRO, CNN+, 40 LATINO, LA SEXTA 1
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 68: T5 ESTRELLAS, T5 SPORT, TELECINCO, FLYMUSIC
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/4 NONE # Canal 69: ANTENA 3, ANTENA.NEOX, ANTENA.NOVA, LA SEXTA 2
diff --git a/util/scan/dvb-t/fi-Aanekoski b/util/scan/dvb-t/fi-Aanekoski
new file mode 100644
index 0000000..e1513fe
--- /dev/null
+++ b/util/scan/dvb-t/fi-Aanekoski
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Aanekoski_Konginkangas b/util/scan/dvb-t/fi-Aanekoski_Konginkangas
new file mode 100644
index 0000000..af7c892
--- /dev/null
+++ b/util/scan/dvb-t/fi-Aanekoski_Konginkangas
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ahtari b/util/scan/dvb-t/fi-Ahtari
new file mode 100644
index 0000000..12a4150
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ahtari
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ala-Vuokki b/util/scan/dvb-t/fi-Ala-Vuokki
new file mode 100644
index 0000000..1e3b99f
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ala-Vuokki
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Alajarvi b/util/scan/dvb-t/fi-Alajarvi
new file mode 100644
index 0000000..9704ea5
--- /dev/null
+++ b/util/scan/dvb-t/fi-Alajarvi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ammansaari b/util/scan/dvb-t/fi-Ammansaari
new file mode 100644
index 0000000..80c1607
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ammansaari
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Anjalankoski b/util/scan/dvb-t/fi-Anjalankoski
new file mode 100644
index 0000000..273bc92
--- /dev/null
+++ b/util/scan/dvb-t/fi-Anjalankoski
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Enontekio_Ahovaara_Raattama b/util/scan/dvb-t/fi-Enontekio_Ahovaara_Raattama
new file mode 100644
index 0000000..0985bcc
--- /dev/null
+++ b/util/scan/dvb-t/fi-Enontekio_Ahovaara_Raattama
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Espoo b/util/scan/dvb-t/fi-Espoo
index dd0619b..2764c44 100644
--- a/util/scan/dvb-t/fi-Espoo
+++ b/util/scan/dvb-t/fi-Espoo
@@ -1,3 +1,6 @@
-# Espoo A-mux (Digita Finland)
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Eurajoki b/util/scan/dvb-t/fi-Eurajoki
new file mode 100644
index 0000000..6ed4e1b
--- /dev/null
+++ b/util/scan/dvb-t/fi-Eurajoki
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Fiskars b/util/scan/dvb-t/fi-Fiskars
new file mode 100644
index 0000000..8e85e63
--- /dev/null
+++ b/util/scan/dvb-t/fi-Fiskars
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Haapavesi b/util/scan/dvb-t/fi-Haapavesi
new file mode 100644
index 0000000..6d8956b
--- /dev/null
+++ b/util/scan/dvb-t/fi-Haapavesi
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hameenkyro_Kyroskoski b/util/scan/dvb-t/fi-Hameenkyro_Kyroskoski
new file mode 100644
index 0000000..91c5c53
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hameenkyro_Kyroskoski
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hameenlinna_Painokangas b/util/scan/dvb-t/fi-Hameenlinna_Painokangas
new file mode 100644
index 0000000..75278af
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hameenlinna_Painokangas
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hanko b/util/scan/dvb-t/fi-Hanko
new file mode 100644
index 0000000..a4430f5
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hanko
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hartola b/util/scan/dvb-t/fi-Hartola
new file mode 100644
index 0000000..817b1d4
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hartola
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Heinavesi b/util/scan/dvb-t/fi-Heinavesi
new file mode 100644
index 0000000..1e26e70
--- /dev/null
+++ b/util/scan/dvb-t/fi-Heinavesi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Heinola b/util/scan/dvb-t/fi-Heinola
new file mode 100644
index 0000000..a2e7f14
--- /dev/null
+++ b/util/scan/dvb-t/fi-Heinola
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hetta b/util/scan/dvb-t/fi-Hetta
new file mode 100644
index 0000000..c9ccb85
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hetta
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Houtskari b/util/scan/dvb-t/fi-Houtskari
new file mode 100644
index 0000000..78f636a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Houtskari
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hyrynsalmi b/util/scan/dvb-t/fi-Hyrynsalmi
new file mode 100644
index 0000000..cae406a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hyrynsalmi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hyrynsalmi_Kyparavaara b/util/scan/dvb-t/fi-Hyrynsalmi_Kyparavaara
new file mode 100644
index 0000000..cae406a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hyrynsalmi_Kyparavaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hyrynsalmi_Paljakka b/util/scan/dvb-t/fi-Hyrynsalmi_Paljakka
new file mode 100644
index 0000000..afca845
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hyrynsalmi_Paljakka
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Hyvinkaa_Musta-Mannisto b/util/scan/dvb-t/fi-Hyvinkaa_Musta-Mannisto
new file mode 100644
index 0000000..8776147
--- /dev/null
+++ b/util/scan/dvb-t/fi-Hyvinkaa_Musta-Mannisto
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ii_Raiskio b/util/scan/dvb-t/fi-Ii_Raiskio
new file mode 100644
index 0000000..7b31831
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ii_Raiskio
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Iisalmi b/util/scan/dvb-t/fi-Iisalmi
new file mode 100644
index 0000000..a6d3546
--- /dev/null
+++ b/util/scan/dvb-t/fi-Iisalmi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ikaalinen b/util/scan/dvb-t/fi-Ikaalinen
new file mode 100644
index 0000000..af90345
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ikaalinen
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ikaalinen_Riitiala b/util/scan/dvb-t/fi-Ikaalinen_Riitiala
new file mode 100644
index 0000000..320ef92
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ikaalinen_Riitiala
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Inari b/util/scan/dvb-t/fi-Inari
new file mode 100644
index 0000000..39c9c0d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Inari
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ivalo_Saarineitamovaara b/util/scan/dvb-t/fi-Ivalo_Saarineitamovaara
new file mode 100644
index 0000000..53e2382
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ivalo_Saarineitamovaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jalasjarvi b/util/scan/dvb-t/fi-Jalasjarvi
new file mode 100644
index 0000000..0aa1215
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jalasjarvi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jamsa_Kaipola b/util/scan/dvb-t/fi-Jamsa_Kaipola
new file mode 100644
index 0000000..7e4cb3b
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jamsa_Kaipola
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jamsa_Kuorevesi_Halli b/util/scan/dvb-t/fi-Jamsa_Kuorevesi_Halli
new file mode 100644
index 0000000..0a59e26
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jamsa_Kuorevesi_Halli
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jamsa_Matkosvuori b/util/scan/dvb-t/fi-Jamsa_Matkosvuori
new file mode 100644
index 0000000..03e1dd9
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jamsa_Matkosvuori
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jamsa_Ouninpohja b/util/scan/dvb-t/fi-Jamsa_Ouninpohja
new file mode 100644
index 0000000..b976550
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jamsa_Ouninpohja
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jamsankoski b/util/scan/dvb-t/fi-Jamsankoski
new file mode 100644
index 0000000..dfb94fb
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jamsankoski
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Joensuu_Vestinkallio b/util/scan/dvb-t/fi-Joensuu_Vestinkallio
new file mode 100644
index 0000000..886380e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Joensuu_Vestinkallio
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Joroinen_Puukkola b/util/scan/dvb-t/fi-Joroinen_Puukkola
new file mode 100644
index 0000000..f600e4b
--- /dev/null
+++ b/util/scan/dvb-t/fi-Joroinen_Puukkola
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Joutsa_Lankia b/util/scan/dvb-t/fi-Joutsa_Lankia
new file mode 100644
index 0000000..e0c7169
--- /dev/null
+++ b/util/scan/dvb-t/fi-Joutsa_Lankia
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Joutseno b/util/scan/dvb-t/fi-Joutseno
new file mode 100644
index 0000000..3e8d231
--- /dev/null
+++ b/util/scan/dvb-t/fi-Joutseno
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Juntusranta b/util/scan/dvb-t/fi-Juntusranta
new file mode 100644
index 0000000..80c1607
--- /dev/null
+++ b/util/scan/dvb-t/fi-Juntusranta
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Juupajoki_Kopsamo b/util/scan/dvb-t/fi-Juupajoki_Kopsamo
new file mode 100644
index 0000000..095a726
--- /dev/null
+++ b/util/scan/dvb-t/fi-Juupajoki_Kopsamo
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jyvaskyla b/util/scan/dvb-t/fi-Jyvaskyla
new file mode 100644
index 0000000..a85ec1e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jyvaskyla
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Jyvaskylan_mlk_Vaajakoski b/util/scan/dvb-t/fi-Jyvaskylan_mlk_Vaajakoski
new file mode 100644
index 0000000..632acb4
--- /dev/null
+++ b/util/scan/dvb-t/fi-Jyvaskylan_mlk_Vaajakoski
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kaavi_Sivakkavaara_Luikonlahti b/util/scan/dvb-t/fi-Kaavi_Sivakkavaara_Luikonlahti
new file mode 100644
index 0000000..3c00447
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kaavi_Sivakkavaara_Luikonlahti
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kajaani_Pollyvaara b/util/scan/dvb-t/fi-Kajaani_Pollyvaara
new file mode 100644
index 0000000..c560b8c
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kajaani_Pollyvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kalajoki b/util/scan/dvb-t/fi-Kalajoki
new file mode 100644
index 0000000..2dfe85a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kalajoki
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kangaslampi b/util/scan/dvb-t/fi-Kangaslampi
new file mode 100644
index 0000000..343beb0
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kangaslampi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kangasniemi_Turkinmaki b/util/scan/dvb-t/fi-Kangasniemi_Turkinmaki
new file mode 100644
index 0000000..6541b8d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kangasniemi_Turkinmaki
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kankaanpaa b/util/scan/dvb-t/fi-Kankaanpaa
new file mode 100644
index 0000000..00813d2
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kankaanpaa
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Karigasniemi b/util/scan/dvb-t/fi-Karigasniemi
new file mode 100644
index 0000000..76dece6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Karigasniemi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Karkkila b/util/scan/dvb-t/fi-Karkkila
new file mode 100644
index 0000000..de76a2c
--- /dev/null
+++ b/util/scan/dvb-t/fi-Karkkila
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Karstula b/util/scan/dvb-t/fi-Karstula
new file mode 100644
index 0000000..2ad386e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Karstula
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Karvia b/util/scan/dvb-t/fi-Karvia
new file mode 100644
index 0000000..6d325cf
--- /dev/null
+++ b/util/scan/dvb-t/fi-Karvia
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kaunispaa b/util/scan/dvb-t/fi-Kaunispaa
new file mode 100644
index 0000000..39c9c0d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kaunispaa
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kemijarvi_Suomutunturi b/util/scan/dvb-t/fi-Kemijarvi_Suomutunturi
new file mode 100644
index 0000000..e3d091e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kemijarvi_Suomutunturi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kerimaki b/util/scan/dvb-t/fi-Kerimaki
new file mode 100644
index 0000000..b049818
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kerimaki
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Keuruu b/util/scan/dvb-t/fi-Keuruu
new file mode 100644
index 0000000..987e99b
--- /dev/null
+++ b/util/scan/dvb-t/fi-Keuruu
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Keuruu_Haapamaki b/util/scan/dvb-t/fi-Keuruu_Haapamaki
new file mode 100644
index 0000000..904aaf1
--- /dev/null
+++ b/util/scan/dvb-t/fi-Keuruu_Haapamaki
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kihnio b/util/scan/dvb-t/fi-Kihnio
new file mode 100644
index 0000000..bd1c15f
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kihnio
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kiihtelysvaara b/util/scan/dvb-t/fi-Kiihtelysvaara
new file mode 100644
index 0000000..b5c5126
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kiihtelysvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kilpisjarvi b/util/scan/dvb-t/fi-Kilpisjarvi
new file mode 100644
index 0000000..083137a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kilpisjarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kittila_Sirkka_Levitunturi b/util/scan/dvb-t/fi-Kittila_Sirkka_Levitunturi
new file mode 100644
index 0000000..f35911f
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kittila_Sirkka_Levitunturi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kolari_Vuolittaja b/util/scan/dvb-t/fi-Kolari_Vuolittaja
new file mode 100644
index 0000000..fd29f57
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kolari_Vuolittaja
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Koli b/util/scan/dvb-t/fi-Koli
new file mode 100644
index 0000000..8da50ba
--- /dev/null
+++ b/util/scan/dvb-t/fi-Koli
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Korpilahti_Vaarunvuori b/util/scan/dvb-t/fi-Korpilahti_Vaarunvuori
new file mode 100644
index 0000000..dfb94fb
--- /dev/null
+++ b/util/scan/dvb-t/fi-Korpilahti_Vaarunvuori
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Korppoo b/util/scan/dvb-t/fi-Korppoo
new file mode 100644
index 0000000..78f636a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Korppoo
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kruunupyy b/util/scan/dvb-t/fi-Kruunupyy
new file mode 100644
index 0000000..d4b7164
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kruunupyy
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kuhmo_Iivantiira b/util/scan/dvb-t/fi-Kuhmo_Iivantiira
new file mode 100644
index 0000000..1fe56f2
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kuhmo_Iivantiira
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gavle b/util/scan/dvb-t/fi-Kuhmo_Lentiira
index 04fe333..8396dd6 100644
--- a/util/scan/dvb-t/se-Gavle
+++ b/util/scan/dvb-t/fi-Kuhmo_Lentiira
@@ -1,6 +1,4 @@
-# Gavle (Senda/Boxer Sweden)
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
-T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kuhmoinen b/util/scan/dvb-t/fi-Kuhmoinen
new file mode 100644
index 0000000..da26764
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kuhmoinen
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kuhmoinen_Harjunsalmi b/util/scan/dvb-t/fi-Kuhmoinen_Harjunsalmi
new file mode 100644
index 0000000..2d8f5a0
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kuhmoinen_Harjunsalmi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kuhmoinen_Puukkoinen b/util/scan/dvb-t/fi-Kuhmoinen_Puukkoinen
new file mode 100644
index 0000000..f62c9b7
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kuhmoinen_Puukkoinen
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kuopio b/util/scan/dvb-t/fi-Kuopio
new file mode 100644
index 0000000..a1b1259
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kuopio
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kustavi_Viherlahti b/util/scan/dvb-t/fi-Kustavi_Viherlahti
new file mode 100644
index 0000000..fc51088
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kustavi_Viherlahti
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kuttanen b/util/scan/dvb-t/fi-Kuttanen
new file mode 100644
index 0000000..09a14ca
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kuttanen
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Kyyjarvi_Noposenaho b/util/scan/dvb-t/fi-Kyyjarvi_Noposenaho
new file mode 100644
index 0000000..e3f877e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Kyyjarvi_Noposenaho
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Lahti b/util/scan/dvb-t/fi-Lahti
new file mode 100644
index 0000000..23f3b29
--- /dev/null
+++ b/util/scan/dvb-t/fi-Lahti
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Lapua b/util/scan/dvb-t/fi-Lapua
new file mode 100644
index 0000000..77adecc
--- /dev/null
+++ b/util/scan/dvb-t/fi-Lapua
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Laukaa b/util/scan/dvb-t/fi-Laukaa
new file mode 100644
index 0000000..dfb94fb
--- /dev/null
+++ b/util/scan/dvb-t/fi-Laukaa
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Laukaa_Vihtavuori b/util/scan/dvb-t/fi-Laukaa_Vihtavuori
new file mode 100644
index 0000000..dfb94fb
--- /dev/null
+++ b/util/scan/dvb-t/fi-Laukaa_Vihtavuori
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Lavia_Lavianjarvi b/util/scan/dvb-t/fi-Lavia_Lavianjarvi
new file mode 100644
index 0000000..928b425
--- /dev/null
+++ b/util/scan/dvb-t/fi-Lavia_Lavianjarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Lieksa_Vieki b/util/scan/dvb-t/fi-Lieksa_Vieki
new file mode 100644
index 0000000..1efc9d6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Lieksa_Vieki
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Lohja b/util/scan/dvb-t/fi-Lohja
new file mode 100644
index 0000000..68287ee
--- /dev/null
+++ b/util/scan/dvb-t/fi-Lohja
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Loimaa b/util/scan/dvb-t/fi-Loimaa
new file mode 100644
index 0000000..c33efc8
--- /dev/null
+++ b/util/scan/dvb-t/fi-Loimaa
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Luhanka b/util/scan/dvb-t/fi-Luhanka
new file mode 100644
index 0000000..da39467
--- /dev/null
+++ b/util/scan/dvb-t/fi-Luhanka
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Luopioinen b/util/scan/dvb-t/fi-Luopioinen
new file mode 100644
index 0000000..486d21e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Luopioinen
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Mantta b/util/scan/dvb-t/fi-Mantta
new file mode 100644
index 0000000..98a821b
--- /dev/null
+++ b/util/scan/dvb-t/fi-Mantta
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Mantyharju b/util/scan/dvb-t/fi-Mantyharju
new file mode 100644
index 0000000..adf0234
--- /dev/null
+++ b/util/scan/dvb-t/fi-Mantyharju
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Mikkeli b/util/scan/dvb-t/fi-Mikkeli
new file mode 100644
index 0000000..c3a9f91
--- /dev/null
+++ b/util/scan/dvb-t/fi-Mikkeli
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Muonio_Olostunturi b/util/scan/dvb-t/fi-Muonio_Olostunturi
new file mode 100644
index 0000000..5750553
--- /dev/null
+++ b/util/scan/dvb-t/fi-Muonio_Olostunturi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nilsia b/util/scan/dvb-t/fi-Nilsia
new file mode 100644
index 0000000..49fb2b9
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nilsia
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nilsia_Keski-Siikajarvi b/util/scan/dvb-t/fi-Nilsia_Keski-Siikajarvi
new file mode 100644
index 0000000..c48b094
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nilsia_Keski-Siikajarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nilsia_Pisa b/util/scan/dvb-t/fi-Nilsia_Pisa
new file mode 100644
index 0000000..928b425
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nilsia_Pisa
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nokia b/util/scan/dvb-t/fi-Nokia
new file mode 100644
index 0000000..fa4e03d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nokia
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 826000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nokia_Siuro_Linnavuori b/util/scan/dvb-t/fi-Nokia_Siuro_Linnavuori
new file mode 100644
index 0000000..448e837
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nokia_Siuro_Linnavuori
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nummi-Pusula_Hyonola b/util/scan/dvb-t/fi-Nummi-Pusula_Hyonola
new file mode 100644
index 0000000..db4ea87
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nummi-Pusula_Hyonola
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Nurmes_Porokyla b/util/scan/dvb-t/fi-Nurmes_Porokyla
new file mode 100644
index 0000000..0585576
--- /dev/null
+++ b/util/scan/dvb-t/fi-Nurmes_Porokyla
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Orivesi_Langelmaki_Talviainen b/util/scan/dvb-t/fi-Orivesi_Langelmaki_Talviainen
new file mode 100644
index 0000000..86f4254
--- /dev/null
+++ b/util/scan/dvb-t/fi-Orivesi_Langelmaki_Talviainen
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Oulu b/util/scan/dvb-t/fi-Oulu
new file mode 100644
index 0000000..e0b88da
--- /dev/null
+++ b/util/scan/dvb-t/fi-Oulu
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Padasjoki b/util/scan/dvb-t/fi-Padasjoki
new file mode 100644
index 0000000..a0da8ab
--- /dev/null
+++ b/util/scan/dvb-t/fi-Padasjoki
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Padasjoki_Arrakoski b/util/scan/dvb-t/fi-Padasjoki_Arrakoski
new file mode 100644
index 0000000..de939c4
--- /dev/null
+++ b/util/scan/dvb-t/fi-Padasjoki_Arrakoski
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Paltamo_Kivesvaara b/util/scan/dvb-t/fi-Paltamo_Kivesvaara
new file mode 100644
index 0000000..ff6a17a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Paltamo_Kivesvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Parikkala b/util/scan/dvb-t/fi-Parikkala
new file mode 100644
index 0000000..3ae4451
--- /dev/null
+++ b/util/scan/dvb-t/fi-Parikkala
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Parkano b/util/scan/dvb-t/fi-Parkano
new file mode 100644
index 0000000..9bcd629
--- /dev/null
+++ b/util/scan/dvb-t/fi-Parkano
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pello b/util/scan/dvb-t/fi-Pello
new file mode 100644
index 0000000..834dc84
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pello
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pello_Ratasvaara b/util/scan/dvb-t/fi-Pello_Ratasvaara
new file mode 100644
index 0000000..6255911
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pello_Ratasvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Perho b/util/scan/dvb-t/fi-Perho
new file mode 100644
index 0000000..de89309
--- /dev/null
+++ b/util/scan/dvb-t/fi-Perho
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pernaja b/util/scan/dvb-t/fi-Pernaja
new file mode 100644
index 0000000..d63da78
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pernaja
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pieksamaki_Halkokumpu b/util/scan/dvb-t/fi-Pieksamaki_Halkokumpu
new file mode 100644
index 0000000..de3fed1
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pieksamaki_Halkokumpu
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pihtipudas b/util/scan/dvb-t/fi-Pihtipudas
new file mode 100644
index 0000000..30baf95
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pihtipudas
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Porvoo_Suomenkyla b/util/scan/dvb-t/fi-Porvoo_Suomenkyla
new file mode 100644
index 0000000..d63da78
--- /dev/null
+++ b/util/scan/dvb-t/fi-Porvoo_Suomenkyla
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Posio b/util/scan/dvb-t/fi-Posio
new file mode 100644
index 0000000..8066848
--- /dev/null
+++ b/util/scan/dvb-t/fi-Posio
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pudasjarvi b/util/scan/dvb-t/fi-Pudasjarvi
new file mode 100644
index 0000000..5ff8ecf
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pudasjarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pudasjarvi_Iso-Syote b/util/scan/dvb-t/fi-Pudasjarvi_Iso-Syote
new file mode 100644
index 0000000..7281f29
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pudasjarvi_Iso-Syote
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pudasjarvi_Kangasvaara b/util/scan/dvb-t/fi-Pudasjarvi_Kangasvaara
new file mode 100644
index 0000000..a550248
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pudasjarvi_Kangasvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Puolanka b/util/scan/dvb-t/fi-Puolanka
new file mode 100644
index 0000000..5b611d5
--- /dev/null
+++ b/util/scan/dvb-t/fi-Puolanka
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pyhatunturi b/util/scan/dvb-t/fi-Pyhatunturi
new file mode 100644
index 0000000..54c59f2
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pyhatunturi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pyhavuori b/util/scan/dvb-t/fi-Pyhavuori
new file mode 100644
index 0000000..3d7adb9
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pyhavuori
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Pylkonmaki_Karankajarvi b/util/scan/dvb-t/fi-Pylkonmaki_Karankajarvi
new file mode 100644
index 0000000..9577e38
--- /dev/null
+++ b/util/scan/dvb-t/fi-Pylkonmaki_Karankajarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Raahe_Mestauskallio b/util/scan/dvb-t/fi-Raahe_Mestauskallio
new file mode 100644
index 0000000..30f86c6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Raahe_Mestauskallio
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Raahe_Piehinki b/util/scan/dvb-t/fi-Raahe_Piehinki
new file mode 100644
index 0000000..2dfe85a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Raahe_Piehinki
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ranua_Haasionmaa b/util/scan/dvb-t/fi-Ranua_Haasionmaa
new file mode 100644
index 0000000..a74bca7
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ranua_Haasionmaa
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ranua_Leppiaho b/util/scan/dvb-t/fi-Ranua_Leppiaho
new file mode 100644
index 0000000..ad2e920
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ranua_Leppiaho
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rautavaara_Angervikko b/util/scan/dvb-t/fi-Rautavaara_Angervikko
new file mode 100644
index 0000000..b2e176e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rautavaara_Angervikko
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rautjarvi_Simpele b/util/scan/dvb-t/fi-Rautjarvi_Simpele
new file mode 100644
index 0000000..34be33d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rautjarvi_Simpele
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ristijarvi b/util/scan/dvb-t/fi-Ristijarvi
new file mode 100644
index 0000000..f0aa969
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ristijarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi b/util/scan/dvb-t/fi-Rovaniemi
new file mode 100644
index 0000000..e3b96b3
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi_Ala-Nampa_Yli-Nampa_Rantalaki b/util/scan/dvb-t/fi-Rovaniemi_Ala-Nampa_Yli-Nampa_Rantalaki
new file mode 100644
index 0000000..43dd796
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi_Ala-Nampa_Yli-Nampa_Rantalaki
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi_Kaihuanvaara b/util/scan/dvb-t/fi-Rovaniemi_Kaihuanvaara
new file mode 100644
index 0000000..a0567ed
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi_Kaihuanvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi_Karhuvaara_Marrasjarvi b/util/scan/dvb-t/fi-Rovaniemi_Karhuvaara_Marrasjarvi
new file mode 100644
index 0000000..fd29f57
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi_Karhuvaara_Marrasjarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi_Marasenkallio b/util/scan/dvb-t/fi-Rovaniemi_Marasenkallio
new file mode 100644
index 0000000..9dbb40d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi_Marasenkallio
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi_Meltaus_Sorviselka b/util/scan/dvb-t/fi-Rovaniemi_Meltaus_Sorviselka
new file mode 100644
index 0000000..43dd796
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi_Meltaus_Sorviselka
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Rovaniemi_Sonka b/util/scan/dvb-t/fi-Rovaniemi_Sonka
new file mode 100644
index 0000000..9dbb40d
--- /dev/null
+++ b/util/scan/dvb-t/fi-Rovaniemi_Sonka
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ruka b/util/scan/dvb-t/fi-Ruka
new file mode 100644
index 0000000..f036154
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ruka
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ruovesi_Storminiemi b/util/scan/dvb-t/fi-Ruovesi_Storminiemi
new file mode 100644
index 0000000..91c5c53
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ruovesi_Storminiemi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Saarijarvi b/util/scan/dvb-t/fi-Saarijarvi
new file mode 100644
index 0000000..5096705
--- /dev/null
+++ b/util/scan/dvb-t/fi-Saarijarvi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Saarijarvi_Kalmari b/util/scan/dvb-t/fi-Saarijarvi_Kalmari
new file mode 100644
index 0000000..9577e38
--- /dev/null
+++ b/util/scan/dvb-t/fi-Saarijarvi_Kalmari
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Saarijarvi_Mahlu b/util/scan/dvb-t/fi-Saarijarvi_Mahlu
new file mode 100644
index 0000000..afca845
--- /dev/null
+++ b/util/scan/dvb-t/fi-Saarijarvi_Mahlu
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Salla_Hirvasvaara b/util/scan/dvb-t/fi-Salla_Hirvasvaara
new file mode 100644
index 0000000..cae406a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Salla_Hirvasvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Salla_Ihistysjanka b/util/scan/dvb-t/fi-Salla_Ihistysjanka
new file mode 100644
index 0000000..8466760
--- /dev/null
+++ b/util/scan/dvb-t/fi-Salla_Ihistysjanka
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Salla_Naruska b/util/scan/dvb-t/fi-Salla_Naruska
new file mode 100644
index 0000000..c07f596
--- /dev/null
+++ b/util/scan/dvb-t/fi-Salla_Naruska
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Salla_Saija b/util/scan/dvb-t/fi-Salla_Saija
new file mode 100644
index 0000000..817b1d4
--- /dev/null
+++ b/util/scan/dvb-t/fi-Salla_Saija
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Salla_Sallatunturi b/util/scan/dvb-t/fi-Salla_Sallatunturi
new file mode 100644
index 0000000..a6d3546
--- /dev/null
+++ b/util/scan/dvb-t/fi-Salla_Sallatunturi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Salo_Isokyla b/util/scan/dvb-t/fi-Salo_Isokyla
new file mode 100644
index 0000000..95320d3
--- /dev/null
+++ b/util/scan/dvb-t/fi-Salo_Isokyla
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Savukoski_Martti_Haarahonganmaa b/util/scan/dvb-t/fi-Savukoski_Martti_Haarahonganmaa
new file mode 100644
index 0000000..8af05b6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Savukoski_Martti_Haarahonganmaa
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Savukoski_Tanhua b/util/scan/dvb-t/fi-Savukoski_Tanhua
new file mode 100644
index 0000000..817b1d4
--- /dev/null
+++ b/util/scan/dvb-t/fi-Savukoski_Tanhua
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Siilinjarvi b/util/scan/dvb-t/fi-Siilinjarvi
new file mode 100644
index 0000000..0d81662
--- /dev/null
+++ b/util/scan/dvb-t/fi-Siilinjarvi
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Sipoo_Galthagen b/util/scan/dvb-t/fi-Sipoo_Galthagen
new file mode 100644
index 0000000..01746cd
--- /dev/null
+++ b/util/scan/dvb-t/fi-Sipoo_Galthagen
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Sodankyla_Pittiovaara b/util/scan/dvb-t/fi-Sodankyla_Pittiovaara
new file mode 100644
index 0000000..cb87094
--- /dev/null
+++ b/util/scan/dvb-t/fi-Sodankyla_Pittiovaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Sulkava_Vaatalanmaki b/util/scan/dvb-t/fi-Sulkava_Vaatalanmaki
new file mode 100644
index 0000000..a232b78
--- /dev/null
+++ b/util/scan/dvb-t/fi-Sulkava_Vaatalanmaki
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Sysma_Liikola b/util/scan/dvb-t/fi-Sysma_Liikola
new file mode 100644
index 0000000..17dead4
--- /dev/null
+++ b/util/scan/dvb-t/fi-Sysma_Liikola
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Taivalkoski b/util/scan/dvb-t/fi-Taivalkoski
new file mode 100644
index 0000000..f62c9b7
--- /dev/null
+++ b/util/scan/dvb-t/fi-Taivalkoski
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Taivalkoski_Taivalvaara b/util/scan/dvb-t/fi-Taivalkoski_Taivalvaara
new file mode 100644
index 0000000..d166ea6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Taivalkoski_Taivalvaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Tammela b/util/scan/dvb-t/fi-Tammela
new file mode 100644
index 0000000..b1711a6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Tammela
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Tammisaari b/util/scan/dvb-t/fi-Tammisaari
new file mode 100644
index 0000000..000c034
--- /dev/null
+++ b/util/scan/dvb-t/fi-Tammisaari
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Tampere b/util/scan/dvb-t/fi-Tampere
index 7e59894..408e9d4 100644
--- a/util/scan/dvb-t/fi-Tampere
+++ b/util/scan/dvb-t/fi-Tampere
@@ -1,6 +1,6 @@
-# Tampere DVB-T (Digita Finland)
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
-
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Tampere_Pyynikki b/util/scan/dvb-t/fi-Tampere_Pyynikki
new file mode 100644
index 0000000..c627058
--- /dev/null
+++ b/util/scan/dvb-t/fi-Tampere_Pyynikki
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Tervola b/util/scan/dvb-t/fi-Tervola
new file mode 100644
index 0000000..a57e255
--- /dev/null
+++ b/util/scan/dvb-t/fi-Tervola
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Turku b/util/scan/dvb-t/fi-Turku
index 5f2d9b4..187d618 100644
--- a/util/scan/dvb-t/fi-Turku
+++ b/util/scan/dvb-t/fi-Turku
@@ -1,3 +1,6 @@
-# Turku A-mux (Digita Finland)
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki b/util/scan/dvb-t/fi-Utsjoki
new file mode 100644
index 0000000..e216a81
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki_Nuorgam_Njallavaara b/util/scan/dvb-t/fi-Utsjoki_Nuorgam_Njallavaara
new file mode 100644
index 0000000..7615f11
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki_Nuorgam_Njallavaara
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki_Nuorgam_raja b/util/scan/dvb-t/fi-Utsjoki_Nuorgam_raja
new file mode 100644
index 0000000..7615f11
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki_Nuorgam_raja
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki_Outakoski b/util/scan/dvb-t/fi-Utsjoki_Outakoski
new file mode 100644
index 0000000..76dece6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki_Outakoski
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki_Polvarniemi b/util/scan/dvb-t/fi-Utsjoki_Polvarniemi
new file mode 100644
index 0000000..76dece6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki_Polvarniemi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki_Rovisuvanto b/util/scan/dvb-t/fi-Utsjoki_Rovisuvanto
new file mode 100644
index 0000000..f3f2e81
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki_Rovisuvanto
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Utsjoki_Tenola b/util/scan/dvb-t/fi-Utsjoki_Tenola
new file mode 100644
index 0000000..7dfd61a
--- /dev/null
+++ b/util/scan/dvb-t/fi-Utsjoki_Tenola
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Uusikaupunki_Orivo b/util/scan/dvb-t/fi-Uusikaupunki_Orivo
new file mode 100644
index 0000000..1bf70a6
--- /dev/null
+++ b/util/scan/dvb-t/fi-Uusikaupunki_Orivo
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vaala b/util/scan/dvb-t/fi-Vaala
new file mode 100644
index 0000000..19faff0
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vaala
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vaasa b/util/scan/dvb-t/fi-Vaasa
new file mode 100644
index 0000000..1e878fd
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vaasa
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Valtimo b/util/scan/dvb-t/fi-Valtimo
new file mode 100644
index 0000000..a2f2df0
--- /dev/null
+++ b/util/scan/dvb-t/fi-Valtimo
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vammala_Jyranvuori b/util/scan/dvb-t/fi-Vammala_Jyranvuori
new file mode 100644
index 0000000..de944ae
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vammala_Jyranvuori
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vammala_Roismala b/util/scan/dvb-t/fi-Vammala_Roismala
new file mode 100644
index 0000000..80fcc91
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vammala_Roismala
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vammala_Savi b/util/scan/dvb-t/fi-Vammala_Savi
new file mode 100644
index 0000000..5ae4303
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vammala_Savi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vantaa_Hakunila b/util/scan/dvb-t/fi-Vantaa_Hakunila
new file mode 100644
index 0000000..2764c44
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vantaa_Hakunila
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Varpaisjarvi_Honkamaki b/util/scan/dvb-t/fi-Varpaisjarvi_Honkamaki
new file mode 100644
index 0000000..c060467
--- /dev/null
+++ b/util/scan/dvb-t/fi-Varpaisjarvi_Honkamaki
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Virrat_Lappavuori b/util/scan/dvb-t/fi-Virrat_Lappavuori
new file mode 100644
index 0000000..d661fde
--- /dev/null
+++ b/util/scan/dvb-t/fi-Virrat_Lappavuori
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vuokatti b/util/scan/dvb-t/fi-Vuokatti
new file mode 100644
index 0000000..382b91e
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vuokatti
@@ -0,0 +1,6 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Vuotso b/util/scan/dvb-t/fi-Vuotso
new file mode 100644
index 0000000..111d043
--- /dev/null
+++ b/util/scan/dvb-t/fi-Vuotso
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ylitornio_Ainiovaara b/util/scan/dvb-t/fi-Ylitornio_Ainiovaara
new file mode 100644
index 0000000..9edae15
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ylitornio_Ainiovaara
@@ -0,0 +1,5 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Ylitornio_Raanujarvi b/util/scan/dvb-t/fi-Ylitornio_Raanujarvi
new file mode 100644
index 0000000..7380a74
--- /dev/null
+++ b/util/scan/dvb-t/fi-Ylitornio_Raanujarvi
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fi-Yllas b/util/scan/dvb-t/fi-Yllas
new file mode 100644
index 0000000..834dc84
--- /dev/null
+++ b/util/scan/dvb-t/fi-Yllas
@@ -0,0 +1,4 @@
+# automatically generated from http://www.digitv.fi/sivu.asp?path=1;8224;9519
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fr-Abbeville b/util/scan/dvb-t/fr-Abbeville
new file mode 100644
index 0000000..d4de766
--- /dev/null
+++ b/util/scan/dvb-t/fr-Abbeville
@@ -0,0 +1,25 @@
+# Abbeville - France (DVB-T transmitter of Abbeville ( LaMotte ) )
+# Abbeville - France (signal DVB-T transmis depuis l'émetteur de LaMotte )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Abbeville - LaMotte ####
+#R1
+T 506000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Agen b/util/scan/dvb-t/fr-Agen
new file mode 100644
index 0000000..3a5798a
--- /dev/null
+++ b/util/scan/dvb-t/fr-Agen
@@ -0,0 +1,25 @@
+# Agen - France (DVB-T transmitter of Agen ( Agglomération ) )
+# Agen - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Agen - Agglomération ####
+#R1
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Ajaccio b/util/scan/dvb-t/fr-Ajaccio
new file mode 100644
index 0000000..d179961
--- /dev/null
+++ b/util/scan/dvb-t/fr-Ajaccio
@@ -0,0 +1,25 @@
+# Ajaccio - France (DVB-T transmitter of Ajaccio ( Baied'Ajaccio ) )
+# Ajaccio - France (signal DVB-T transmis depuis l'émetteur de Baied'Ajaccio )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Ajaccio - Baied'Ajaccio ####
+#R1
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Albi b/util/scan/dvb-t/fr-Albi
new file mode 100644
index 0000000..e847d24
--- /dev/null
+++ b/util/scan/dvb-t/fr-Albi
@@ -0,0 +1,25 @@
+# Albi - France (DVB-T transmitter of Albi ( Agglomération ) )
+# Albi - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Albi - Agglomération ####
+#R1
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 818000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Alençon b/util/scan/dvb-t/fr-Alençon
new file mode 100644
index 0000000..73747f7
--- /dev/null
+++ b/util/scan/dvb-t/fr-Alençon
@@ -0,0 +1,25 @@
+# Alençon - France (DVB-T transmitter of Alençon ( Montsd'Amain ) )
+# Alençon - France (signal DVB-T transmis depuis l'émetteur de Montsd'Amain )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Alençon - Montsd'Amain ####
+#R1
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 826000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Ales b/util/scan/dvb-t/fr-Ales
new file mode 100644
index 0000000..d467996
--- /dev/null
+++ b/util/scan/dvb-t/fr-Ales
@@ -0,0 +1,25 @@
+# Alès - France (DVB-T transmitter of Alès ( Agglomération ) )
+# Alès - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Alès - Agglomération ####
+#R1
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Ales-Bouquet b/util/scan/dvb-t/fr-Ales-Bouquet
new file mode 100644
index 0000000..d5c176f
--- /dev/null
+++ b/util/scan/dvb-t/fr-Ales-Bouquet
@@ -0,0 +1,25 @@
+# Alès - France (DVB-T transmitter of Alès ( MontBouquet ) )
+# Alès - France (signal DVB-T transmis depuis l'émetteur de MontBouquet )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Alès - MontBouquet ####
+#R1
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Amiens b/util/scan/dvb-t/fr-Amiens
new file mode 100644
index 0000000..b4e06b4
--- /dev/null
+++ b/util/scan/dvb-t/fr-Amiens
@@ -0,0 +1,25 @@
+# Amiens - France (DVB-T transmitter of Amiens ( LesSaintJust ) )
+# Amiens - France (signal DVB-T transmis depuis l'émetteur de LesSaintJust )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Amiens - LesSaintJust ####
+#R1
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Angers b/util/scan/dvb-t/fr-Angers
new file mode 100644
index 0000000..18abe02
--- /dev/null
+++ b/util/scan/dvb-t/fr-Angers
@@ -0,0 +1,25 @@
+# Angers - France (DVB-T transmitter of Angers ( RochefortsurLoire ) )
+# Angers - France (signal DVB-T transmis depuis l'émetteur de RochefortsurLoire )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Angers - RochefortsurLoire ####
+#R1
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Annecy b/util/scan/dvb-t/fr-Annecy
new file mode 100644
index 0000000..02da6a3
--- /dev/null
+++ b/util/scan/dvb-t/fr-Annecy
@@ -0,0 +1,25 @@
+# Annecy - France (DVB-T transmitter of Annecy ( Agglomération ) )
+# Annecy - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Annecy - Agglomération ####
+#R1
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 482000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 530000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 506000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 834000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Arcachon b/util/scan/dvb-t/fr-Arcachon
new file mode 100644
index 0000000..1e7f959
--- /dev/null
+++ b/util/scan/dvb-t/fr-Arcachon
@@ -0,0 +1,25 @@
+# Arcachon - France (DVB-T transmitter of Arcachon ( Agglomération ) )
+# Arcachon - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Arcachon - Agglomération ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Argenton b/util/scan/dvb-t/fr-Argenton
new file mode 100644
index 0000000..f9db8b6
--- /dev/null
+++ b/util/scan/dvb-t/fr-Argenton
@@ -0,0 +1,25 @@
+# Argenton - France (DVB-T transmitter of Argenton ( Malicornay ) )
+# Argenton - France (signal DVB-T transmis depuis l'émetteur de Malicornay )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Argenton - Malicornay ####
+#R1
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Aubenas b/util/scan/dvb-t/fr-Aubenas
new file mode 100644
index 0000000..0ac067e
--- /dev/null
+++ b/util/scan/dvb-t/fr-Aubenas
@@ -0,0 +1,25 @@
+# Aubenas - France (DVB-T transmitter of Aubenas ( Nord ) )
+# Aubenas - France (signal DVB-T transmis depuis l'émetteur de Nord )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Aubenas - Nord ####
+#R1
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Aurillac b/util/scan/dvb-t/fr-Aurillac
new file mode 100644
index 0000000..9537c43
--- /dev/null
+++ b/util/scan/dvb-t/fr-Aurillac
@@ -0,0 +1,25 @@
+# Aurillac - France (DVB-T transmitter of Aurillac ( Agglomération ) )
+# Aurillac - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Aurillac - Agglomération ####
+#R1
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Autun b/util/scan/dvb-t/fr-Autun
new file mode 100644
index 0000000..83baa2c
--- /dev/null
+++ b/util/scan/dvb-t/fr-Autun
@@ -0,0 +1,25 @@
+# Autun - France (DVB-T transmitter of Autun ( BoisduRoi ) )
+# Autun - France (signal DVB-T transmis depuis l'émetteur de BoisduRoi )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Autun - BoisduRoi ####
+#R1
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 834000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 850000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Auxerre b/util/scan/dvb-t/fr-Auxerre
new file mode 100644
index 0000000..4436ca9
--- /dev/null
+++ b/util/scan/dvb-t/fr-Auxerre
@@ -0,0 +1,25 @@
+# Auxerre - France (DVB-T transmitter of Auxerre ( Molesmes ) )
+# Auxerre - France (signal DVB-T transmis depuis l'émetteur de Molesmes )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Auxerre - Molesmes ####
+#R1
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 794000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Avignon b/util/scan/dvb-t/fr-Avignon
new file mode 100644
index 0000000..32aeeaf
--- /dev/null
+++ b/util/scan/dvb-t/fr-Avignon
@@ -0,0 +1,25 @@
+# Avignon - France (DVB-T transmitter of Avignon ( MontVentoux ) )
+# Avignon - France (signal DVB-T transmis depuis l'émetteur de MontVentoux )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Avignon - MontVentoux ####
+#R1
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-BarleDuc b/util/scan/dvb-t/fr-BarleDuc
new file mode 100644
index 0000000..47b7c0a
--- /dev/null
+++ b/util/scan/dvb-t/fr-BarleDuc
@@ -0,0 +1,25 @@
+# BarleDuc - France (DVB-T transmitter of BarleDuc ( Willeroncourt ) )
+# BarleDuc - France (signal DVB-T transmis depuis l'émetteur de Willeroncourt )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### BarleDuc - Willeroncourt ####
+#R1
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 658000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Bastia b/util/scan/dvb-t/fr-Bastia
new file mode 100644
index 0000000..36dec27
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bastia
@@ -0,0 +1,25 @@
+# Bastia - France (DVB-T transmitter of Bastia ( SerradiPigno ) )
+# Bastia - France (signal DVB-T transmis depuis l'émetteur de SerradiPigno )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Bastia - SerradiPigno ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Bayonne b/util/scan/dvb-t/fr-Bayonne
new file mode 100644
index 0000000..ada99fc
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bayonne
@@ -0,0 +1,25 @@
+# Bayonne - France (DVB-T transmitter of Bayonne ( LaRhune ) )
+# Bayonne - France (signal DVB-T transmis depuis l'émetteur de LaRhune )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Bayonne - LaRhune ####
+#R1
+T 826000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Bergerac b/util/scan/dvb-t/fr-Bergerac
new file mode 100644
index 0000000..5cbaf85
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bergerac
@@ -0,0 +1,25 @@
+# Bergerac - France (DVB-T transmitter of Bergerac ( Audrix ) )
+# Bergerac - France (signal DVB-T transmis depuis l'émetteur de Audrix )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Bergerac - Audrix ####
+#R1
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 482000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Besançon b/util/scan/dvb-t/fr-Besançon
new file mode 100644
index 0000000..08d1a68
--- /dev/null
+++ b/util/scan/dvb-t/fr-Besançon
@@ -0,0 +1,25 @@
+# Besançon - France (DVB-T transmitter of Besançon ( Brégille ) )
+# Besançon - France (signal DVB-T transmis depuis l'émetteur de Brégille )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Besançon - Brégille ####
+#R1
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Bordeaux b/util/scan/dvb-t/fr-Bordeaux
new file mode 100644
index 0000000..5efba4e
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bordeaux
@@ -0,0 +1,9 @@
+# Bordeaux - France (DVB-T transmitter of Bouliac or Cauderan)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Bordeaux-Bouliac b/util/scan/dvb-t/fr-Bordeaux-Bouliac
new file mode 100644
index 0000000..8017d4e
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bordeaux-Bouliac
@@ -0,0 +1,25 @@
+# Bordeaux - France (DVB-T transmitter of Bordeaux ( BordeauxEst ) )
+# Bordeaux - France (signal DVB-T transmis depuis l'émetteur de BordeauxEst )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Bordeaux - BordeauxEst ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 658000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Bordeaux-Cauderan b/util/scan/dvb-t/fr-Bordeaux-Cauderan
new file mode 100644
index 0000000..3733231
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bordeaux-Cauderan
@@ -0,0 +1,25 @@
+# Bordeaux - France (DVB-T transmitter of Bordeaux ( Caudéran ) )
+# Bordeaux - France (signal DVB-T transmis depuis l'émetteur de Caudéran )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Bordeaux - Caudéran ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 482000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Boulogne b/util/scan/dvb-t/fr-Boulogne
new file mode 100644
index 0000000..644172b
--- /dev/null
+++ b/util/scan/dvb-t/fr-Boulogne
@@ -0,0 +1,25 @@
+# Boulogne - France (DVB-T transmitter of Boulogne ( MontLambert ) )
+# Boulogne - France (signal DVB-T transmis depuis l'émetteur de MontLambert )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Boulogne - MontLambert ####
+#R1
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Bourges b/util/scan/dvb-t/fr-Bourges
new file mode 100644
index 0000000..a99105b
--- /dev/null
+++ b/util/scan/dvb-t/fr-Bourges
@@ -0,0 +1,25 @@
+# Bourges - France (DVB-T transmitter of Bourges ( CollinesduSancerrois ) )
+# Bourges - France (signal DVB-T transmis depuis l'émetteur de CollinesduSancerrois )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Bourges - CollinesduSancerrois ####
+#R1
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 522000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Brest b/util/scan/dvb-t/fr-Brest
new file mode 100644
index 0000000..e16fe38
--- /dev/null
+++ b/util/scan/dvb-t/fr-Brest
@@ -0,0 +1,9 @@
+# Brest - France
+# Emetteur du Roch Tredudon
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 482000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 506000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 490000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 530000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 514000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Brive b/util/scan/dvb-t/fr-Brive
new file mode 100644
index 0000000..7b3ce53
--- /dev/null
+++ b/util/scan/dvb-t/fr-Brive
@@ -0,0 +1,25 @@
+# Brive - France (DVB-T transmitter of Brive ( Lissac ) )
+# Brive - France (signal DVB-T transmis depuis l'émetteur de Lissac )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Brive - Lissac ####
+#R1
+T 530000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 658000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Caen b/util/scan/dvb-t/fr-Caen
new file mode 100644
index 0000000..d82bd89
--- /dev/null
+++ b/util/scan/dvb-t/fr-Caen
@@ -0,0 +1,25 @@
+# Caen - France (DVB-T transmitter of Caen ( CaenNord ) )
+# Caen - France (signal DVB-T transmis depuis l'émetteur de CaenNord )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Caen - CaenNord ####
+#R1
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Caen-Pincon b/util/scan/dvb-t/fr-Caen-Pincon
new file mode 100644
index 0000000..a749b05
--- /dev/null
+++ b/util/scan/dvb-t/fr-Caen-Pincon
@@ -0,0 +1,25 @@
+# Caen - France (DVB-T transmitter of Caen ( MontPinçon ) )
+# Caen - France (signal DVB-T transmis depuis l'émetteur de MontPinçon )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Caen - MontPinçon ####
+#R1
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Cannes b/util/scan/dvb-t/fr-Cannes
new file mode 100644
index 0000000..2f841af
--- /dev/null
+++ b/util/scan/dvb-t/fr-Cannes
@@ -0,0 +1,25 @@
+# Cannes - France (DVB-T transmitter of Cannes ( Vallauris ) )
+# Cannes - France (signal DVB-T transmis depuis l'émetteur de Vallauris )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Cannes - Vallauris ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Carcassonne b/util/scan/dvb-t/fr-Carcassonne
new file mode 100644
index 0000000..f5545b8
--- /dev/null
+++ b/util/scan/dvb-t/fr-Carcassonne
@@ -0,0 +1,25 @@
+# Carcassonne - France (DVB-T transmitter of Carcassonne ( MontagneNoire ) )
+# Carcassonne - France (signal DVB-T transmis depuis l'émetteur de MontagneNoire )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Carcassonne - MontagneNoire ####
+#R1
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Chambery b/util/scan/dvb-t/fr-Chambery
new file mode 100644
index 0000000..caf0eee
--- /dev/null
+++ b/util/scan/dvb-t/fr-Chambery
@@ -0,0 +1,30 @@
+# Chambéry - France (DVB-T transmitter of Chambéry ( Nondéfini ) )
+# Chambéry - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Chambéry - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Chambéry n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Chartres b/util/scan/dvb-t/fr-Chartres
new file mode 100644
index 0000000..0207b84
--- /dev/null
+++ b/util/scan/dvb-t/fr-Chartres
@@ -0,0 +1,25 @@
+# Chartres - France (DVB-T transmitter of Chartres ( Montlandon ) )
+# Chartres - France (signal DVB-T transmis depuis l'émetteur de Montlandon )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Chartres - Montlandon ####
+#R1
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Chennevieres b/util/scan/dvb-t/fr-Chennevieres
new file mode 100644
index 0000000..253f5bf
--- /dev/null
+++ b/util/scan/dvb-t/fr-Chennevieres
@@ -0,0 +1,25 @@
+# ParisEst - France (DVB-T transmitter of ParisEst ( Chennevières ) )
+# ParisEst - France (signal DVB-T transmis depuis l'émetteur de Chennevières )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### ParisEst - Chennevières ####
+#R1
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Cherbourg b/util/scan/dvb-t/fr-Cherbourg
new file mode 100644
index 0000000..21be7f5
--- /dev/null
+++ b/util/scan/dvb-t/fr-Cherbourg
@@ -0,0 +1,25 @@
+# Cherbourg - France (DVB-T transmitter of Cherbourg ( Digosville ) )
+# Cherbourg - France (signal DVB-T transmis depuis l'émetteur de Digosville )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Cherbourg - Digosville ####
+#R1
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-ClermontFerrand b/util/scan/dvb-t/fr-ClermontFerrand
new file mode 100644
index 0000000..4610b61
--- /dev/null
+++ b/util/scan/dvb-t/fr-ClermontFerrand
@@ -0,0 +1,25 @@
+# Clermont-Ferrand - France (DVB-T transmitter of Clermont-Ferrand ( PuydeDôme ) )
+# Clermont-Ferrand - France (signal DVB-T transmis depuis l'émetteur de PuydeDôme )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Clermont-Ferrand - PuydeDôme ####
+#R1
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Cluses b/util/scan/dvb-t/fr-Cluses
new file mode 100644
index 0000000..e40863c
--- /dev/null
+++ b/util/scan/dvb-t/fr-Cluses
@@ -0,0 +1,30 @@
+# Cluses - France (DVB-T transmitter of Cluses ( Nondéfini ) )
+# Cluses - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Cluses - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Cluses n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Dieppe b/util/scan/dvb-t/fr-Dieppe
new file mode 100644
index 0000000..b059bae
--- /dev/null
+++ b/util/scan/dvb-t/fr-Dieppe
@@ -0,0 +1,25 @@
+# Dieppe - France (DVB-T transmitter of Dieppe ( Neuville ) )
+# Dieppe - France (signal DVB-T transmis depuis l'émetteur de Neuville )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Dieppe - Neuville ####
+#R1
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Dijon b/util/scan/dvb-t/fr-Dijon
new file mode 100644
index 0000000..a077ad1
--- /dev/null
+++ b/util/scan/dvb-t/fr-Dijon
@@ -0,0 +1,30 @@
+# Dijon - France (DVB-T transmitter of Dijon ( Nondéfini ) )
+# Dijon - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Dijon - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Dijon n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Dunkerque b/util/scan/dvb-t/fr-Dunkerque
new file mode 100644
index 0000000..58ad7b6
--- /dev/null
+++ b/util/scan/dvb-t/fr-Dunkerque
@@ -0,0 +1,30 @@
+# Dunkerque - France (DVB-T transmitter of Dunkerque ( Nondéfini ) )
+# Dunkerque - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Dunkerque - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Dunkerque n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Epinal b/util/scan/dvb-t/fr-Epinal
new file mode 100644
index 0000000..b3cf1e3
--- /dev/null
+++ b/util/scan/dvb-t/fr-Epinal
@@ -0,0 +1,25 @@
+# Epinal - France (DVB-T transmitter of Epinal ( BoisdelaVierge ) )
+# Epinal - France (signal DVB-T transmis depuis l'émetteur de BoisdelaVierge )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Epinal - BoisdelaVierge ####
+#R1
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Evreux b/util/scan/dvb-t/fr-Evreux
new file mode 100644
index 0000000..64da79f
--- /dev/null
+++ b/util/scan/dvb-t/fr-Evreux
@@ -0,0 +1,25 @@
+# Evreux - France (DVB-T transmitter of Evreux ( Netreville ) )
+# Evreux - France (signal DVB-T transmis depuis l'émetteur de Netreville )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Evreux - Netreville ####
+#R1
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Forbach b/util/scan/dvb-t/fr-Forbach
new file mode 100644
index 0000000..8ed748a
--- /dev/null
+++ b/util/scan/dvb-t/fr-Forbach
@@ -0,0 +1,30 @@
+# Forbach - France (DVB-T transmitter of Forbach ( Nondéfini ) )
+# Forbach - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Forbach - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Forbach n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Gex b/util/scan/dvb-t/fr-Gex
new file mode 100644
index 0000000..1d5f0dd
--- /dev/null
+++ b/util/scan/dvb-t/fr-Gex
@@ -0,0 +1,30 @@
+# Gex - France (DVB-T transmitter of Gex ( Nondéfini ) )
+# Gex - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Gex - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Gex n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Grenoble b/util/scan/dvb-t/fr-Grenoble
new file mode 100644
index 0000000..94103f0
--- /dev/null
+++ b/util/scan/dvb-t/fr-Grenoble
@@ -0,0 +1,25 @@
+# Grenoble - France (DVB-T transmitter of Grenoble ( ToursansVenin ) )
+# Grenoble - France (signal DVB-T transmis depuis l'émetteur de ToursansVenin )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Grenoble - ToursansVenin ####
+#R1
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 474000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 522000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Gueret b/util/scan/dvb-t/fr-Gueret
new file mode 100644
index 0000000..0704ef6
--- /dev/null
+++ b/util/scan/dvb-t/fr-Gueret
@@ -0,0 +1,25 @@
+# Guéret - France (DVB-T transmitter of Guéret ( StLégerleGueretois ) )
+# Guéret - France (signal DVB-T transmis depuis l'émetteur de StLégerleGueretois )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Guéret - StLégerleGueretois ####
+#R1
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Hirson b/util/scan/dvb-t/fr-Hirson
new file mode 100644
index 0000000..a3c244d
--- /dev/null
+++ b/util/scan/dvb-t/fr-Hirson
@@ -0,0 +1,30 @@
+# Hirson - France (DVB-T transmitter of Hirson ( Nondéfini ) )
+# Hirson - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Hirson - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Hirson n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Hyeres b/util/scan/dvb-t/fr-Hyeres
new file mode 100644
index 0000000..6dbb93d
--- /dev/null
+++ b/util/scan/dvb-t/fr-Hyeres
@@ -0,0 +1,25 @@
+# Hyères - France (DVB-T transmitter of Hyères ( CapBenat ) )
+# Hyères - France (signal DVB-T transmis depuis l'émetteur de CapBenat )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Hyères - CapBenat ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-LaRochelle b/util/scan/dvb-t/fr-LaRochelle
new file mode 100644
index 0000000..309f4a9
--- /dev/null
+++ b/util/scan/dvb-t/fr-LaRochelle
@@ -0,0 +1,25 @@
+# Rochelle(La) - France (DVB-T transmitter of Rochelle(La) ( Mireuil ) )
+# Rochelle(La) - France (signal DVB-T transmis depuis l'émetteur de Mireuil )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Rochelle(La) - Mireuil ####
+#R1
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Laval b/util/scan/dvb-t/fr-Laval
new file mode 100644
index 0000000..61c0aa0
--- /dev/null
+++ b/util/scan/dvb-t/fr-Laval
@@ -0,0 +1,25 @@
+# Laval - France (DVB-T transmitter of Laval ( MontRochard ) )
+# Laval - France (signal DVB-T transmis depuis l'émetteur de MontRochard )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Laval - MontRochard ####
+#R1
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 794000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-LeCreusot b/util/scan/dvb-t/fr-LeCreusot
new file mode 100644
index 0000000..ff4cb0b
--- /dev/null
+++ b/util/scan/dvb-t/fr-LeCreusot
@@ -0,0 +1,25 @@
+# Creusot(Le) - France (DVB-T transmitter of Creusot(Le) ( MontStVincent ) )
+# Creusot(Le) - France (signal DVB-T transmis depuis l'émetteur de MontStVincent )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Creusot(Le) - MontStVincent ####
+#R1
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 794000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 818000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-LeHavre b/util/scan/dvb-t/fr-LeHavre
new file mode 100644
index 0000000..bf3bb0e
--- /dev/null
+++ b/util/scan/dvb-t/fr-LeHavre
@@ -0,0 +1,25 @@
+# Havre(Le) - France (DVB-T transmitter of Havre(Le) ( Harfleur ) )
+# Havre(Le) - France (signal DVB-T transmis depuis l'émetteur de Harfleur )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Havre(Le) - Harfleur ####
+#R1
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-LeMans b/util/scan/dvb-t/fr-LeMans
new file mode 100644
index 0000000..323018f
--- /dev/null
+++ b/util/scan/dvb-t/fr-LeMans
@@ -0,0 +1,21 @@
+# Le Mans - France (DVB-T transmitter of Mayet)
+# Le Mans - France (signal DVB-T transmis depuis l'émetteur de Mayet )
+# Pour plus d'informations vous pouvez consulter :
+# - le topic sur l'émetteur de Mayet sur le forum du site tvnt.net :
+# http://www.tvnt.net/forum/viewtopic.php?t=48
+# - le site de TDF : http://tnt.niv2.com/72100-LE-MANS.html
+# contact : Matthieu Duchemin <alkahan@free.fr>
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# R1 : Canal 26
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R2 : Canal 23
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R3 : Canal 56
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R4 : Canal 31
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R5 : Canal 37
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R6 : Canal 36
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-LePuyEnVelay b/util/scan/dvb-t/fr-LePuyEnVelay
new file mode 100644
index 0000000..e1a95e9
--- /dev/null
+++ b/util/scan/dvb-t/fr-LePuyEnVelay
@@ -0,0 +1,25 @@
+# PuyenVelay(Le) - France (DVB-T transmitter of PuyenVelay(Le) ( Agglomération ) )
+# PuyenVelay(Le) - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### PuyenVelay(Le) - Agglomération ####
+#R1
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Lille b/util/scan/dvb-t/fr-Lille
new file mode 100644
index 0000000..c30c520
--- /dev/null
+++ b/util/scan/dvb-t/fr-Lille
@@ -0,0 +1,30 @@
+# Lille - France (DVB-T transmitter of Lille ( Nondéfini ) )
+# Lille - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Lille - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Lille n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Lille-Lambersart b/util/scan/dvb-t/fr-Lille-Lambersart
new file mode 100644
index 0000000..6a7c377
--- /dev/null
+++ b/util/scan/dvb-t/fr-Lille-Lambersart
@@ -0,0 +1,25 @@
+# Lille - France (DVB-T transmitter of Lille ( Lambersart ) )
+# Lille - France (signal DVB-T transmis depuis l'émetteur de Lambersart )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Lille - Lambersart ####
+#R1
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-LilleT2 b/util/scan/dvb-t/fr-LilleT2
new file mode 100644
index 0000000..b629f70
--- /dev/null
+++ b/util/scan/dvb-t/fr-LilleT2
@@ -0,0 +1,13 @@
+# Lille - France (DVB-T transmitter of Lambersart)
+#offset of 167000 for Cinergy T2. Other type of card users need to replace 167 by 000
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#R2
+T 538167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R4
+T 546167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R3
+T 562167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R6
+T 586167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R1
+T 594167000 8MHz 3/4 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/fr-Limoges b/util/scan/dvb-t/fr-Limoges
new file mode 100644
index 0000000..1581bcf
--- /dev/null
+++ b/util/scan/dvb-t/fr-Limoges
@@ -0,0 +1,25 @@
+# Limoges - France (DVB-T transmitter of Limoges ( Agglomération ) )
+# Limoges - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Limoges - Agglomération ####
+#R1
+T 826000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Longwy b/util/scan/dvb-t/fr-Longwy
new file mode 100644
index 0000000..9881bfc
--- /dev/null
+++ b/util/scan/dvb-t/fr-Longwy
@@ -0,0 +1,30 @@
+# Longwy - France (DVB-T transmitter of Longwy ( Nondéfini ) )
+# Longwy - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Longwy - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Longwy n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Lorient b/util/scan/dvb-t/fr-Lorient
new file mode 100644
index 0000000..0b3e307
--- /dev/null
+++ b/util/scan/dvb-t/fr-Lorient
@@ -0,0 +1,25 @@
+# Lorient - France (DVB-T transmitter of Lorient ( Ploemer ) )
+# Lorient - France (signal DVB-T transmis depuis l'émetteur de Ploemer )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Lorient - Ploemer ####
+#R1
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 818000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 794000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Lyon-Fourviere b/util/scan/dvb-t/fr-Lyon-Fourviere
new file mode 100644
index 0000000..17ca1f7
--- /dev/null
+++ b/util/scan/dvb-t/fr-Lyon-Fourviere
@@ -0,0 +1,19 @@
+# Lyon - France (DVB-T transmitter of Fourvière)
+# Lyon - France (signal DVB-T transmis depuis l'émetteur de Fourvière)
+# see : http://tnt.niv2.com/69000-LYON.html
+# contact : Nicolas Estre <n_estre@yahoo.fr>
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval
+hierarchy
+# R1 : Canal 56
+T 754167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R2 : Canal 36
+T 594167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R3 : Canal 21
+T 474167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R4 : Canal 54
+T 738167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R5 : Canal 27
+T 522167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R6 : Canal 24
+T 498167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Lyon-Pilat b/util/scan/dvb-t/fr-Lyon-Pilat
new file mode 100644
index 0000000..71cd3a5
--- /dev/null
+++ b/util/scan/dvb-t/fr-Lyon-Pilat
@@ -0,0 +1,17 @@
+# Lyon - France (DVB-T transmitter of Mt Pilat)
+# Lyon - France (signal DVB-T transmis depuis l'émetteur du Mont Pilat)
+# see : http://tnt.niv2.com/69000-LYON.html
+# contact : Nicolas Estre <n_estre@yahoo.fr>
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# R1 : Canal 45
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R2 : Canal 36
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R3 : Canal 39
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R4 : Canal 54
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R5 : Canal 42
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+# R6 : Canal 47
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Macon b/util/scan/dvb-t/fr-Macon
new file mode 100644
index 0000000..dddebc5
--- /dev/null
+++ b/util/scan/dvb-t/fr-Macon
@@ -0,0 +1,30 @@
+# Mâcon - France (DVB-T transmitter of Mâcon ( Nondéfini ) )
+# Mâcon - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Mâcon - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Mâcon n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Mantes b/util/scan/dvb-t/fr-Mantes
new file mode 100644
index 0000000..d9a1b7e
--- /dev/null
+++ b/util/scan/dvb-t/fr-Mantes
@@ -0,0 +1,25 @@
+# Mantes - France (DVB-T transmitter of Mantes ( MaudétourenVexin ) )
+# Mantes - France (signal DVB-T transmis depuis l'émetteur de MaudétourenVexin )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Mantes - MaudétourenVexin ####
+#R1
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 650000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 674000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 626000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Marseille b/util/scan/dvb-t/fr-Marseille
new file mode 100644
index 0000000..7a57003
--- /dev/null
+++ b/util/scan/dvb-t/fr-Marseille
@@ -0,0 +1,6 @@
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Maubeuge b/util/scan/dvb-t/fr-Maubeuge
new file mode 100644
index 0000000..e865c02
--- /dev/null
+++ b/util/scan/dvb-t/fr-Maubeuge
@@ -0,0 +1,30 @@
+# Maubeuge - France (DVB-T transmitter of Maubeuge ( Nondéfini ) )
+# Maubeuge - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Maubeuge - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Maubeuge n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Meaux b/util/scan/dvb-t/fr-Meaux
new file mode 100644
index 0000000..4837bf4
--- /dev/null
+++ b/util/scan/dvb-t/fr-Meaux
@@ -0,0 +1,25 @@
+# Meaux - France (DVB-T transmitter of Meaux ( Mareuil ) )
+# Meaux - France (signal DVB-T transmis depuis l'émetteur de Mareuil )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Meaux - Mareuil ####
+#R1
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 818000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Mende b/util/scan/dvb-t/fr-Mende
new file mode 100644
index 0000000..39bd41e
--- /dev/null
+++ b/util/scan/dvb-t/fr-Mende
@@ -0,0 +1,25 @@
+# Mende - France (DVB-T transmitter of Mende ( TrucdeFortunio ) )
+# Mende - France (signal DVB-T transmis depuis l'émetteur de TrucdeFortunio )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Mende - TrucdeFortunio ####
+#R1
+T 522000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 474000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Menton b/util/scan/dvb-t/fr-Menton
new file mode 100644
index 0000000..f48fd72
--- /dev/null
+++ b/util/scan/dvb-t/fr-Menton
@@ -0,0 +1,25 @@
+# Menton - France (DVB-T transmitter of Menton ( CapMartin ) )
+# Menton - France (signal DVB-T transmis depuis l'émetteur de CapMartin )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Menton - CapMartin ####
+#R1
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 842000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 658000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Metz b/util/scan/dvb-t/fr-Metz
new file mode 100644
index 0000000..e018031
--- /dev/null
+++ b/util/scan/dvb-t/fr-Metz
@@ -0,0 +1,30 @@
+# Metz - France (DVB-T transmitter of Metz ( Nondéfini ) )
+# Metz - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Metz - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Metz n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Mezieres b/util/scan/dvb-t/fr-Mezieres
new file mode 100644
index 0000000..62dd087
--- /dev/null
+++ b/util/scan/dvb-t/fr-Mezieres
@@ -0,0 +1,30 @@
+# Mézières - France (DVB-T transmitter of Mézières ( Nondéfini ) )
+# Mézières - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Mézières - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Mézières n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Montlucon b/util/scan/dvb-t/fr-Montlucon
new file mode 100644
index 0000000..64cd64a
--- /dev/null
+++ b/util/scan/dvb-t/fr-Montlucon
@@ -0,0 +1,25 @@
+# Montluçon - France (DVB-T transmitter of Montluçon ( Agglomération ) )
+# Montluçon - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Montluçon - Agglomération ####
+#R1
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 826000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Montpellier b/util/scan/dvb-t/fr-Montpellier
new file mode 100644
index 0000000..c17bb8e
--- /dev/null
+++ b/util/scan/dvb-t/fr-Montpellier
@@ -0,0 +1,25 @@
+# Montpellier - France (DVB-T transmitter of Montpellier ( SaintBaudille ) )
+# Montpellier - France (signal DVB-T transmis depuis l'émetteur de SaintBaudille )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Montpellier - SaintBaudille ####
+#R1
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Mulhouse b/util/scan/dvb-t/fr-Mulhouse
new file mode 100644
index 0000000..da420fd
--- /dev/null
+++ b/util/scan/dvb-t/fr-Mulhouse
@@ -0,0 +1,26 @@
+# Mulhouse - France (DVB-T transmitter of Mulhouse ( Belvédère ) )
+# Mulhouse - France (signal DVB-T transmis depuis l'émetteur du Belvédère )
+#
+# Fichier réalisé par :
+# IUT COLMAR DEPARTEMENT RESEAUX ET TELECOMMUNICATIONS
+# Novembre 2007
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# R1 - ch 53 : France 2, 3 (Alsace), 5, LCP et Arte (France)
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+
+# R2 - ch 55 : I-TELE, BFM TV, Direct 8, Gulli, Virgin 17 (ex-Europe 2 TV) et France 4
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+
+# R3 - ch 54 : TV payante : CANAL+, CANAL+ CINEMA, CANAL+ SPORT, PLANETE, CANAL J et TPS STAR
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+
+# R4 - ch 37 : M6, W9 et NT1 + TV payante : PARIS PREMIERE, TF6 et AB1
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+
+# R5
+# ch 66, candidat a la TVHD
+
+# R6 - ch 65 : TF 1, NRJ 12 et TMC + TV payante : Eurosport France et LCI
+T 826000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Nancy b/util/scan/dvb-t/fr-Nancy
new file mode 100644
index 0000000..f4ff7b8
--- /dev/null
+++ b/util/scan/dvb-t/fr-Nancy
@@ -0,0 +1,25 @@
+# Nancy - France (DVB-T transmitter of Nancy ( Nondéfini ) )
+# Nancy - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Nancy - Nondéfini ####
+#R1
+T 522166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R2
+T 682166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R3
+T 794166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R4
+T 770166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R5
+T 498166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R6
+T 826166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Nantes b/util/scan/dvb-t/fr-Nantes
new file mode 100644
index 0000000..22d9e21
--- /dev/null
+++ b/util/scan/dvb-t/fr-Nantes
@@ -0,0 +1,8 @@
+# Nantes - France
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-NeufchatelEnBray b/util/scan/dvb-t/fr-NeufchatelEnBray
new file mode 100644
index 0000000..1eeb5ea
--- /dev/null
+++ b/util/scan/dvb-t/fr-NeufchatelEnBray
@@ -0,0 +1,25 @@
+# Neufchatel-en-Bray - France (DVB-T transmitter of Neufchatel-en-Bray ( Croixdalle ) )
+# Neufchatel-en-Bray - France (signal DVB-T transmis depuis l'émetteur de Croixdalle )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Neufchatel-en-Bray - Croixdalle ####
+#R1
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 522000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Nice b/util/scan/dvb-t/fr-Nice
new file mode 100644
index 0000000..c122ab7
--- /dev/null
+++ b/util/scan/dvb-t/fr-Nice
@@ -0,0 +1,25 @@
+# Nice - France (DVB-T transmitter of Nice ( MontAlban ) )
+# Nice - France (signal DVB-T transmis depuis l'émetteur de MontAlban )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Nice - MontAlban ####
+#R1
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Niort b/util/scan/dvb-t/fr-Niort
new file mode 100644
index 0000000..396489a
--- /dev/null
+++ b/util/scan/dvb-t/fr-Niort
@@ -0,0 +1,7 @@
+# Niort - France (DVB-T transmitter of Niort-Maisonnay)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 602000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 738000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 778000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 802000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Orleans b/util/scan/dvb-t/fr-Orleans
new file mode 100644
index 0000000..c42ccc5
--- /dev/null
+++ b/util/scan/dvb-t/fr-Orleans
@@ -0,0 +1,17 @@
+# Orléans / France
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#
+# R2: canal 38 : direct8 TMC Gulli europe2 bfm itélé
+T 610166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+
+# R1: canal 46 : F2 F3 F4 F5 arte LCP
+T 674166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+
+# R4: canal 48 : M6 W9 NT1
+T 690166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+
+# R6: canal 51 : TF1 NRJ12
+T 714166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+
+# R3: canal 63 : canalplus
+T 810166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Paris b/util/scan/dvb-t/fr-Paris
new file mode 100644
index 0000000..bfb93a8
--- /dev/null
+++ b/util/scan/dvb-t/fr-Paris
@@ -0,0 +1,19 @@
+# Paris - France - various DVB-T transmitters
+# contributed by Alexis de Lattre <alexis@via.ecp.fr>
+# Paris - Tour Eiffel : 21 24 27 29 32 35
+# Paris Est - Chennevières : 35 51 54 57 60 63
+# Paris Nord - Sannois : 35 51 54 57 60 63
+# Paris Sud - Villebon : 35 51 56 57 60 63
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 498166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 522166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 538166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 562166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 586166000 8MHz 3/4 NONE QAM64 8k 1/8 NONE
+T 714166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 738166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 754166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 762166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 786166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 810166000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Parthenay b/util/scan/dvb-t/fr-Parthenay
new file mode 100644
index 0000000..567ebe1
--- /dev/null
+++ b/util/scan/dvb-t/fr-Parthenay
@@ -0,0 +1,25 @@
+# Parthenay - France (DVB-T transmitter of Parthenay ( Amailloux ) )
+# Parthenay - France (signal DVB-T transmis depuis l'émetteur de Amailloux )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Parthenay - Amailloux ####
+#R1
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Perpignan b/util/scan/dvb-t/fr-Perpignan
new file mode 100644
index 0000000..d0b74ce
--- /dev/null
+++ b/util/scan/dvb-t/fr-Perpignan
@@ -0,0 +1,25 @@
+# Perpignan - France (DVB-T transmitter of Perpignan ( PicdeNeulos ) )
+# Perpignan - France (signal DVB-T transmis depuis l'émetteur de PicdeNeulos )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Perpignan - PicdeNeulos ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 474000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 522000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Poitiers b/util/scan/dvb-t/fr-Poitiers
new file mode 100644
index 0000000..2a0ed31
--- /dev/null
+++ b/util/scan/dvb-t/fr-Poitiers
@@ -0,0 +1,25 @@
+# Poitiers - France (DVB-T transmitter of Poitiers ( Agglomération ) )
+# Poitiers - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Poitiers - Agglomération ####
+#R1
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 794000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Privas b/util/scan/dvb-t/fr-Privas
new file mode 100644
index 0000000..cd27631
--- /dev/null
+++ b/util/scan/dvb-t/fr-Privas
@@ -0,0 +1,25 @@
+# Privas - France (DVB-T transmitter of Privas ( Sud ) )
+# Privas - France (signal DVB-T transmis depuis l'émetteur de Sud )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Privas - Sud ####
+#R1
+T 658000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Reims b/util/scan/dvb-t/fr-Reims
new file mode 100644
index 0000000..ab7c4e8
--- /dev/null
+++ b/util/scan/dvb-t/fr-Reims
@@ -0,0 +1,25 @@
+# Reims - France (DVB-T transmitter of Reims ( Hautvillers ) )
+# Reims - France (signal DVB-T transmis depuis l'émetteur de Hautvillers )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Reims - Hautvillers ####
+#R1
+T 562000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 554000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 666000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Rennes b/util/scan/dvb-t/fr-Rennes
new file mode 100644
index 0000000..3287413
--- /dev/null
+++ b/util/scan/dvb-t/fr-Rennes
@@ -0,0 +1,7 @@
+# Rennes - France
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 586000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 650000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 674000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
+T 626000000 8MHz 1/2 NONE QAM16 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Roanne b/util/scan/dvb-t/fr-Roanne
new file mode 100644
index 0000000..224ca9f
--- /dev/null
+++ b/util/scan/dvb-t/fr-Roanne
@@ -0,0 +1,25 @@
+# Roanne - France (DVB-T transmitter of Roanne ( Perreux ) )
+# Roanne - France (signal DVB-T transmis depuis l'émetteur de Perreux )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Roanne - Perreux ####
+#R1
+T 474000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 498000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 522000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Rouen b/util/scan/dvb-t/fr-Rouen
new file mode 100644
index 0000000..5808155
--- /dev/null
+++ b/util/scan/dvb-t/fr-Rouen
@@ -0,0 +1,8 @@
+# Rouen - France
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-SaintEtienne b/util/scan/dvb-t/fr-SaintEtienne
new file mode 100644
index 0000000..740f223
--- /dev/null
+++ b/util/scan/dvb-t/fr-SaintEtienne
@@ -0,0 +1,25 @@
+# Saint-Etienne - France (DVB-T transmitter of Saint-Etienne ( CroixduGuisay ) )
+# Saint-Etienne - France (signal DVB-T transmis depuis l'émetteur de CroixduGuisay )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Saint-Etienne - CroixduGuisay ####
+#R1
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 618000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 538000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-SaintRaphael b/util/scan/dvb-t/fr-SaintRaphael
new file mode 100644
index 0000000..da3a503
--- /dev/null
+++ b/util/scan/dvb-t/fr-SaintRaphael
@@ -0,0 +1,25 @@
+# Saint-Raphaël - France (DVB-T transmitter of Saint-Raphaël ( Picdel'Ours ) )
+# Saint-Raphaël - France (signal DVB-T transmis depuis l'émetteur de Picdel'Ours )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Saint-Raphaël - Picdel'Ours ####
+#R1
+T 490000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 642000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Sannois b/util/scan/dvb-t/fr-Sannois
new file mode 100644
index 0000000..c3e99e1
--- /dev/null
+++ b/util/scan/dvb-t/fr-Sannois
@@ -0,0 +1,25 @@
+# ParisNord - France (DVB-T transmitter of ParisNord ( Sannois ) )
+# ParisNord - France (signal DVB-T transmis depuis l'émetteur de Sannois )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### ParisNord - Sannois ####
+#R1
+T 586000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 786000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 762000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Sarrebourg b/util/scan/dvb-t/fr-Sarrebourg
new file mode 100644
index 0000000..f6b8d57
--- /dev/null
+++ b/util/scan/dvb-t/fr-Sarrebourg
@@ -0,0 +1,30 @@
+# Sarrebourg - France (DVB-T transmitter of Sarrebourg ( Nondéfini ) )
+# Sarrebourg - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Sarrebourg - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Sarrebourg n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Sens b/util/scan/dvb-t/fr-Sens
new file mode 100644
index 0000000..3de1a26
--- /dev/null
+++ b/util/scan/dvb-t/fr-Sens
@@ -0,0 +1,25 @@
+# Sens - France (DVB-T transmitter of Sens ( GisylesNobles ) )
+# Sens - France (signal DVB-T transmis depuis l'émetteur de GisylesNobles )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Sens - GisylesNobles ####
+#R1
+T 778000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 794000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 770000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 802000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Strasbourg b/util/scan/dvb-t/fr-Strasbourg
new file mode 100644
index 0000000..dbbf546
--- /dev/null
+++ b/util/scan/dvb-t/fr-Strasbourg
@@ -0,0 +1,30 @@
+# Strasbourg - France (DVB-T transmitter of Strasbourg ( Nondéfini ) )
+# Strasbourg - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Strasbourg - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Strasbourg n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Toulon b/util/scan/dvb-t/fr-Toulon
new file mode 100644
index 0000000..2fc9e9a
--- /dev/null
+++ b/util/scan/dvb-t/fr-Toulon
@@ -0,0 +1,25 @@
+# Toulon - France (DVB-T transmitter of Toulon ( CapSicié ) )
+# Toulon - France (signal DVB-T transmis depuis l'émetteur de CapSicié )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Toulon - CapSicié ####
+#R1
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Toulouse b/util/scan/dvb-t/fr-Toulouse
new file mode 100644
index 0000000..4c0ba20
--- /dev/null
+++ b/util/scan/dvb-t/fr-Toulouse
@@ -0,0 +1,8 @@
+# Toulouse - France (DVB-T transmitter of Bohnoure)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 698167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 722167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 714167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 746167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 730167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Toulouse-Midi b/util/scan/dvb-t/fr-Toulouse-Midi
new file mode 100644
index 0000000..df51107
--- /dev/null
+++ b/util/scan/dvb-t/fr-Toulouse-Midi
@@ -0,0 +1,25 @@
+# Toulouse - France (DVB-T transmitter of Toulouse ( PicduMidi ) )
+# Toulouse - France (signal DVB-T transmis depuis l'émetteur de PicduMidi )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Toulouse - PicduMidi ####
+#R1
+T 738000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 482000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Tours b/util/scan/dvb-t/fr-Tours
new file mode 100644
index 0000000..9ad9f71
--- /dev/null
+++ b/util/scan/dvb-t/fr-Tours
@@ -0,0 +1,25 @@
+# Tours - France (DVB-T transmitter of Tours ( Chissay ) )
+# Tours - France (signal DVB-T transmis depuis l'émetteur de Chissay )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Tours - Chissay ####
+#R1
+T 578000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 610000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 810000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 690000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 714000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Troyes b/util/scan/dvb-t/fr-Troyes
new file mode 100644
index 0000000..bcafe8b
--- /dev/null
+++ b/util/scan/dvb-t/fr-Troyes
@@ -0,0 +1,25 @@
+# Troyes - France (DVB-T transmitter of Troyes ( LesRiceys ) )
+# Troyes - France (signal DVB-T transmis depuis l'émetteur de LesRiceys )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Troyes - LesRiceys ####
+#R1
+T 482000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 594000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 514000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 506000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 530000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Ussel b/util/scan/dvb-t/fr-Ussel
new file mode 100644
index 0000000..de2a58c
--- /dev/null
+++ b/util/scan/dvb-t/fr-Ussel
@@ -0,0 +1,25 @@
+# Ussel - France (DVB-T transmitter of Ussel ( Meymac ) )
+# Ussel - France (signal DVB-T transmis depuis l'émetteur de Meymac )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Ussel - Meymac ####
+#R1
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 634000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 658000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 682000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Valence b/util/scan/dvb-t/fr-Valence
new file mode 100644
index 0000000..4b74003
--- /dev/null
+++ b/util/scan/dvb-t/fr-Valence
@@ -0,0 +1,25 @@
+# Valence - France (DVB-T transmitter of Valence ( StRomaindeLerps ) )
+# Valence - France (signal DVB-T transmis depuis l'émetteur de StRomaindeLerps )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Valence - StRomaindeLerps ####
+#R1
+T 706000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+T 722000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+T 546000000 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+T 570000000 8MHz AUTO NONE QAM64 8k AUTO NONE
diff --git a/util/scan/dvb-t/fr-Valenciennes b/util/scan/dvb-t/fr-Valenciennes
new file mode 100644
index 0000000..36d0642
--- /dev/null
+++ b/util/scan/dvb-t/fr-Valenciennes
@@ -0,0 +1,30 @@
+# Valenciennes - France (DVB-T transmitter of Valenciennes ( Nondéfini ) )
+# Valenciennes - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Valenciennes - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Valenciennes n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Vannes b/util/scan/dvb-t/fr-Vannes
new file mode 100644
index 0000000..06439cb
--- /dev/null
+++ b/util/scan/dvb-t/fr-Vannes
@@ -0,0 +1,7 @@
+# Vannes / France
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 698167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 762167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 778167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 818167000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Villebon b/util/scan/dvb-t/fr-Villebon
new file mode 100644
index 0000000..ec173d7
--- /dev/null
+++ b/util/scan/dvb-t/fr-Villebon
@@ -0,0 +1,22 @@
+# Paris - France (DVB-T transmitter of Villebon )
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# Villebon - France (DVB-T transmitter of Villebon (South of Paris))
+# Villebon - France (signal DVB-T transmis depuis l'émetteur de Villebon (Sud de Paris))
+# see : http://tnt.niv2.com/91140-VILLEBON-SUR-YVETTE.html
+# contact : Nicolas Estre <n_estre@yahoo.fr>
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### VILLEBON SUR YVETTE ####
+#R1 35
+T 586000000 8MHz 3/4 NONE QAM64 8k 1/8 NONE
+#R2 56
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R3 60
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R4 63
+T 810000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R5 51
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+#R6 57
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/fr-Vittel b/util/scan/dvb-t/fr-Vittel
new file mode 100644
index 0000000..8c55b23
--- /dev/null
+++ b/util/scan/dvb-t/fr-Vittel
@@ -0,0 +1,30 @@
+# Vittel - France (DVB-T transmitter of Vittel ( Nondéfini ) )
+# Vittel - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Vittel - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Vittel n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/fr-Voiron b/util/scan/dvb-t/fr-Voiron
new file mode 100644
index 0000000..04405c6
--- /dev/null
+++ b/util/scan/dvb-t/fr-Voiron
@@ -0,0 +1,30 @@
+# Voiron - France (DVB-T transmitter of Voiron ( Nondéfini ) )
+# Voiron - France (signal DVB-T transmis depuis l'émetteur de Nondéfini )
+#
+# ATTENTION ! Ce fichier a ete construit automatiquement a partir
+# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
+# en Avril 2006. Si vous constatez des problemes et voulez apporter des
+# modifications au fichier, envoyez le fichier modifie a
+# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
+# ou a l'auteur du fichier :
+# Nicolas Estre <n_estre@yahoo.fr>
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#### Voiron - Nondéfini ####
+#R1
+#T FREQ1 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R2
+#T FREQ2 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R3
+#T FREQ3 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R4
+#T FREQ4 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R5
+#T FREQ5 8MHz AUTO NONE QAM64 8k AUTO NONE
+#R6
+#T FREQ6 8MHz AUTO NONE QAM64 8k AUTO NONE
+##############################################################
+# en Avril 2006, l'emetteur pour Voiron n'etait pas defini
+# Vous devez donc modifier les frequences manuellement.
+# SVP Renvoyez le fichier mis a jour aux contacts ci-dessus.
+##############################################################
diff --git a/util/scan/dvb-t/gr-Athens b/util/scan/dvb-t/gr-Athens
new file mode 100644
index 0000000..85cf6d7
--- /dev/null
+++ b/util/scan/dvb-t/gr-Athens
@@ -0,0 +1,3 @@
+# Initial scan config for Digital DVB-T (Ert) in Athens Greece
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690000000 8MHz 3/4 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/hr-Zagreb b/util/scan/dvb-t/hr-Zagreb
new file mode 100644
index 0000000..b385c87
--- /dev/null
+++ b/util/scan/dvb-t/hr-Zagreb
@@ -0,0 +1,3 @@
+# DVB-T Hamburg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 3/4 NONE AUTO 8k 1/32 NONE # CH27:
diff --git a/util/scan/dvb-t/is-Reykjavik b/util/scan/dvb-t/is-Reykjavik
new file mode 100644
index 0000000..da5e3c6
--- /dev/null
+++ b/util/scan/dvb-t/is-Reykjavik
@@ -0,0 +1,13 @@
+# Initial scan config for Digital Ãsland in Iceland
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 794000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Aosta b/util/scan/dvb-t/it-Aosta
new file mode 100644
index 0000000..486407d
--- /dev/null
+++ b/util/scan/dvb-t/it-Aosta
@@ -0,0 +1,21 @@
+# Italia / Aosta (it-Aosta) -- mailto: Marco <lovebuzz@email.it>
+#
+# A me funziona solo il Mux Mediaset 2 non riesco a capire come mai...
+# (magari colpa della mia pinnacle pctv 301i saa7133)
+# Gli altri Mux inseriti li ho inseriti come da sito http://www.digitv.it...
+#
+# Chi avesse news o riuscisse a venirne a capo usando anche gli altri mux potrebbe scrivermi
+# inviare una maila kaffeine-user@lists.sf.net per aggiornare/correggere questo file...
+#
+# MUX-A RAI
+T 226500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 474000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MBONE
+T 746000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 762000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 770000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TIMB1
+T 786000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Bari b/util/scan/dvb-t/it-Bari
new file mode 100644
index 0000000..5be8ac4
--- /dev/null
+++ b/util/scan/dvb-t/it-Bari
@@ -0,0 +1,18 @@
+# Italy, Bari
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX-A RAI
+T 219500000 7MHz 2/3 AUTO QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 546000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 514000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 226500000 7MHz 2/3 AUTO QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 826000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MBONE
+T 498000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TIMB1
+T 530000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TeleNorba, TelePuglia, altro...
+T 794000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Bologna b/util/scan/dvb-t/it-Bologna
new file mode 100644
index 0000000..dcd8e35
--- /dev/null
+++ b/util/scan/dvb-t/it-Bologna
@@ -0,0 +1,28 @@
+# DVB-T Collserola (Barcelona)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#TeleSanterno
+T 186000000 7MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#RaiA
+T 203500000 7MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#Sestarete / Rete 7
+T 212500000 7MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#Modena
+T 219500000 7MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#ReteA, Camera e Senato
+T 594000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#Sestarete / Rete 7
+T 610000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#DFree
+T 634000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#Mediaset Mux-B
+T 698000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#La7
+T 714000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#RaiB
+T 722000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#Mediaset Mux-A
+T 794000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#TeleSanterno
+T 802000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
+#LA7-2
+T 842000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Bolzano b/util/scan/dvb-t/it-Bolzano
new file mode 100644
index 0000000..de50c1e
--- /dev/null
+++ b/util/scan/dvb-t/it-Bolzano
@@ -0,0 +1,5 @@
+# DVB-T Bolzano
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+#RAS DVB-t NETWORK
+T 698000000 8MHz 2/3 2/3 QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/it-Cagliari b/util/scan/dvb-t/it-Cagliari
new file mode 100644
index 0000000..9dcaf53
--- /dev/null
+++ b/util/scan/dvb-t/it-Cagliari
@@ -0,0 +1,31 @@
+# DVB-T Cagliari
+# MUX DFREE
+T 730000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX LA7/MTV
+T 474000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET1
+T 826000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET2
+T 562000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-A RAI
+T 546000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 530000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TCS
+T 658000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# VIDEOLINA
+T 610000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TIMEDIA MUX A
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 650000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# T 474000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TIMEDIA MUX B
+T 177500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 602000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# T 177500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# SUPER TV
+# T 650000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Caivano b/util/scan/dvb-t/it-Caivano
new file mode 100644
index 0000000..c823a6f
--- /dev/null
+++ b/util/scan/dvb-t/it-Caivano
@@ -0,0 +1,14 @@
+#################################
+# DVB-T Caivano(NA) 80023 Italy #
+# update: 25/05/2007 #
+# by Nicola Costanzo #
+#################################
+
+# MUX LA7/MTV
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-A RAI
+T 722000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Catania b/util/scan/dvb-t/it-Catania
new file mode 100644
index 0000000..c4d0849
--- /dev/null
+++ b/util/scan/dvb-t/it-Catania
@@ -0,0 +1,27 @@
+# it-Catania
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# MUX DFREE (Canale 5,Italia1,SportItalia,LCI,RadioItalia Tv)
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 690000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX LA7/MTV (La 7,MTV ITALIA,Canale D,Music Box)
+#T 586000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX RTI (Rete 4,Class News,Sole 24 Ore TV,BBC World)
+T 586000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX MEDIASET 1
+T 226500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 834000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX MEDIASET 2
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 650000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX-A RAI (Rai Utile,Rai Doc,RaiSportSAT,RaiNews24,Rai EDU1)
+T 610000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX-B RAI (Rai Utile,Rai Doc,RaiSportSAT,RaiNews24,Rai EDU1)
+T 482000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Conero b/util/scan/dvb-t/it-Conero
new file mode 100644
index 0000000..318775f
--- /dev/null
+++ b/util/scan/dvb-t/it-Conero
@@ -0,0 +1,8 @@
+# Italia / Conero (it-Conero) -- mailto: simon <f.simon@email.it>
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# C50
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C46
+T 674000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C21
+T 474000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Firenze b/util/scan/dvb-t/it-Firenze
new file mode 100644
index 0000000..2ebe9e6
--- /dev/null
+++ b/util/scan/dvb-t/it-Firenze
@@ -0,0 +1,20 @@
+# This channel list is made by Michele Ficarra
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX-A RAI
+T 554000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 682000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 826000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX La7/MTV
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 738000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MBON
+T 778000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX Digitoscana
+T 219500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX Tele37
+T 786000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Genova b/util/scan/dvb-t/it-Genova
new file mode 100644
index 0000000..5b5c670
--- /dev/null
+++ b/util/scan/dvb-t/it-Genova
@@ -0,0 +1,12 @@
+# Italia / Genova (it-Genova) - Angelo Conforti <angeloxx@angeloxx.it>
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX-A RAI
+T 498000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 219500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX La7/MTV
+T 682000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 770000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX Mediaset
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Livorno b/util/scan/dvb-t/it-Livorno
new file mode 100644
index 0000000..bf83a4a
--- /dev/null
+++ b/util/scan/dvb-t/it-Livorno
@@ -0,0 +1,15 @@
+# This channel list is made by G.U.L.LI. LIvorno's Linux Users Group
+# Thanks to: Alessandro Guarguaglini, Stefano Lenzi
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX-A RAI
+T 698000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 658000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 754000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX La7/MTV
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 586000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Milano b/util/scan/dvb-t/it-Milano
new file mode 100644
index 0000000..2b70cd1
--- /dev/null
+++ b/util/scan/dvb-t/it-Milano
@@ -0,0 +1,15 @@
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX-A RAI
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 482000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-A MEDIASET
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-A MEDIASET-2
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX La7/MTV
+T 506000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE 2
+T 538000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Pagnacco b/util/scan/dvb-t/it-Pagnacco
new file mode 100644
index 0000000..c6f482d
--- /dev/null
+++ b/util/scan/dvb-t/it-Pagnacco
@@ -0,0 +1,27 @@
+# Italia / Pagnacco (it-Pagnacco)
+# DVB-T Pagnacco (Italia)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# MUX-A RAI
+
+T 602000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+
+# MUX-B RAI
+
+T 490000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+T 226500000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+
+# MUX-Dfree
+
+T 634000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+T 594000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+
+# MUX-LA7/MTV
+
+T 522000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+
+# Mediaset
+
+T 818000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE
+
+# Europa
diff --git a/util/scan/dvb-t/it-Palermo b/util/scan/dvb-t/it-Palermo
new file mode 100644
index 0000000..8043acd
--- /dev/null
+++ b/util/scan/dvb-t/it-Palermo
@@ -0,0 +1,23 @@
+# Palermo, Italy
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# MUX DFREE (Canale 5,Italia1,SportItalia,LCI,RadioItalia Tv)
+T 754000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 602000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX LA7/MTV (La 7,MTV ITALIA,Canale D,Music Box)
+#T 730000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX RTI (Rete 4,Class News,Sole 24 Ore TV,BBC World)
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX MEDIASET 2
+T 682000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 650000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX-A RAI (Rai Utile,Rai Doc,RaiSportSAT,RaiNews24,Rai EDU1)
+T 610000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+
+# MUX-B RAI (Rai Utile,Rai Doc,RaiSportSAT,RaiNews24,Rai EDU1)
+T 482000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Pisa b/util/scan/dvb-t/it-Pisa
new file mode 100644
index 0000000..5990402
--- /dev/null
+++ b/util/scan/dvb-t/it-Pisa
@@ -0,0 +1,18 @@
+# This channel list is made by G.U.L.LI. LIvorno's Linux Users Group
+# Thanks to: Alessandro Guarguaglini, Stefano Lenzi
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX-A RAI
+T 698000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 658000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 634000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 618000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE
+T 746000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 754000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MBONE
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX TIMB1
+T 762000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Roma b/util/scan/dvb-t/it-Roma
new file mode 100644
index 0000000..4463074
--- /dev/null
+++ b/util/scan/dvb-t/it-Roma
@@ -0,0 +1,16 @@
+# DVB-T Roma
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX DFREE
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX La7/MTV
+T 730000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 1
+T 626000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET 2
+T 762000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-A RAI
+T 698000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 186000000 7MHz 2/3 2/3 QAM64 8k 1/32 NONE
+# SUPER 3
+T 538000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Sassari b/util/scan/dvb-t/it-Sassari
new file mode 100644
index 0000000..c81254e
--- /dev/null
+++ b/util/scan/dvb-t/it-Sassari
@@ -0,0 +1,33 @@
+# DVB-T Sassari Channels List by frippertronics@alice.it ;)
+# MUX DFREE
+T 746000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX LA7/MTV
+T 826000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET1
+T 802000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX MEDIASET2
+T 634000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-A RAI
+T 786000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 530000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX-B RAI
+T 842000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 858000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MBONE
+T 738000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TCS
+T 658000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# VIDEOLINA
+T 610000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TIMEDIA MUX A
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 650000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 850000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# T 474000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 810000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# TIMEDIA MUX B
+T 177500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+T 602000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# T 177500000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# SUPER TV
+# T 650000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Torino b/util/scan/dvb-t/it-Torino
new file mode 100644
index 0000000..4587a21
--- /dev/null
+++ b/util/scan/dvb-t/it-Torino
@@ -0,0 +1,13 @@
+# DVB-T Torino (Italia)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#MUX-A RAI
+T 834000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+#MUX-B RAI
+T 514000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+#MUX RTI
+T 474000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+#MUX LA7
+T 850000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 602000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+#MUX DFREE
+T 650000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/it-Trieste b/util/scan/dvb-t/it-Trieste
new file mode 100644
index 0000000..1839cdf
--- /dev/null
+++ b/util/scan/dvb-t/it-Trieste
@@ -0,0 +1,23 @@
+# Trieste, Italy
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# MUX MEDIASET 1 (Class News, 24Ore TV, Coming soon, BBC World, Boing, Mediaset Premium)
+T 778000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+T 474000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+#
+# MUX-B RAI (Rai Doc-Futura, RaiSportSAT, RaiNotizie24, Rai EDU1, Sat2000, Radio1, Radio2, Radio3, FDAuditorium)
+T 682000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+#
+# MUX-A RAI (Rai Uno, Rai Due, Rai Tre, Rai Utile)
+T 602000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+#
+# MUX DFREE (Rete 4, Italia 1, Sportitalia, LCI / Prima, Si Live24)
+T 754000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+#
+# MUX (All Music)
+T 666000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+#
+# MUX (Triveneta)
+T 698000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
+#
+# MUX (La7 Telemarket Retecapri MTv italia Sitcom Uno)
+T 674000000 8MHz 2/3 1/1 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Varese b/util/scan/dvb-t/it-Varese
new file mode 100644
index 0000000..045b56c
--- /dev/null
+++ b/util/scan/dvb-t/it-Varese
@@ -0,0 +1,16 @@
+# Italia / Varese -- mailto: b.gabriele <gb.dvbch@dveprojects.com>
+#
+# From: http://www.dgtvi.it/copertura.aspx
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#
+# MUX-A RAI VHF H2 226,5 O CAMPO DEI FIORI
+T 226500000 7MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX DFREE UHF C50 706 V CAMPO DEI FIORI
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX LA7-MTV UHF C37 602 V CAMPO DEI FIORI
+T 602000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX RTI UHF C26 514 O CAMPO DEI FIORI PRIMA CAPPELLA
+T 514000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# MUX RTI UHF C38 514 V CAMPO DEI FIORI ALBERGO
+T 610000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/it-Venezia b/util/scan/dvb-t/it-Venezia
new file mode 100644
index 0000000..be454e4
--- /dev/null
+++ b/util/scan/dvb-t/it-Venezia
@@ -0,0 +1,19 @@
+# Italia / Venzia (it-Venezia) -- mailto: Rob <rob.davis@libero.it>
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+#
+# According to Eurosat 1/2006
+#
+# C50 - MediaSet
+T 706000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C37 - Rai A - Doesn't work in Mestre though
+T 602000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C23 -Rai B
+T 490000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C64 DFree
+T 818000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C65 La 7
+T 826000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C58 Mediaset 2
+T 770000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
+# C36 DFree
+T 594000000 8MHz 2/3 1/2 QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/lu-All b/util/scan/dvb-t/lu-All
new file mode 100644
index 0000000..aa30d7c
--- /dev/null
+++ b/util/scan/dvb-t/lu-All
@@ -0,0 +1,5 @@
+# DVB-T Luxembourg [2007-11-18]
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 191500000 7MHz 2/3 NONE QAM16 8k 1/8 NONE # Kanal 7 M6, RTL 8, LUXE.TV
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/16 NONE # Kanal 24 club RTL, RTL TVI, plug TV, RTL 4, RTL 5, RTL 7
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/16 NONE # Kanal 27 RTL TeleLetz, 2 ten RTL
diff --git a/util/scan/dvb-t/lv-Riga b/util/scan/dvb-t/lv-Riga
new file mode 100644
index 0000000..0fb9b9a
--- /dev/null
+++ b/util/scan/dvb-t/lv-Riga
@@ -0,0 +1,25 @@
+# Latvia - Riga (lv-Riga)
+# Generated by Raimonds Cicans
+# UTF8 encoding
+
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# DLRTC
+T 610000000 8MHz 3/4 NONE QAM64 8k 1/8 NONE # Weak signal! VÄjÅ¡ signÄls! Слабый Ñигнал!
+
+# Baltkom TV
+T 650000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+T 658000000 8MHz 1/2 1/2 QPSK 8k 1/4 NONE
+T 666000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+T 690000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+T 778000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+T 834000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+
+# WARNING!
+# Some applications detect incorrect guard-interval.
+
+# UZMANĪBU!
+# Dažas programmas nekorekti nosaka "guard-interval" parametru.
+
+# Ð’ÐИМÐÐИЕ!
+# Ðекоторые программы некорректно определÑÑŽÑ‚ параметр "guard-interval"
diff --git a/util/scan/dvb-t/nl-All b/util/scan/dvb-t/nl-All
new file mode 100644
index 0000000..f01a086
--- /dev/null
+++ b/util/scan/dvb-t/nl-All
@@ -0,0 +1,38 @@
+# The Netherlands, whole country
+# Created from http://home.planet.nl/~ploe2070/fmtv/dvbt/digitenne-kpntv.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 482000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 514000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 546000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 562000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 578000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 618000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 642000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 666000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 690000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 706000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 722000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 738000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 746000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 786000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
+T 826000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 834000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/nl-AlphenaandenRijn b/util/scan/dvb-t/nl-AlphenaandenRijn
deleted file mode 100644
index f95d3a4..0000000
--- a/util/scan/dvb-t/nl-AlphenaandenRijn
+++ /dev/null
@@ -1,7 +0,0 @@
-# Digitenne (Alphen aan den Rijn, The Netherlands)
-# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 474000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 578000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 722000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 762000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 818000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/nl-Randstad b/util/scan/dvb-t/nl-Randstad
deleted file mode 100644
index da1a74d..0000000
--- a/util/scan/dvb-t/nl-Randstad
+++ /dev/null
@@ -1,7 +0,0 @@
-# Digitenne (Randstad, The Netherlands)
-# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 474000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 490000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 578000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 762000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
-T 818000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/nz-Waiatarua b/util/scan/dvb-t/nz-Waiatarua
new file mode 100644
index 0000000..2fbea4f
--- /dev/null
+++ b/util/scan/dvb-t/nz-Waiatarua
@@ -0,0 +1,13 @@
+# Waiatarua, Auckland NZ
+#
+# Channel allocation details for NZ can be found at
+# http://www.rsm.govt.nz/cms/policy-and-planning/current-projects/broadcasting/digital-television-2007-frequency-plan
+#
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+# Multiplex DA
+T 538000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# Multiplex DB
+T 570000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
+# Multiplex DC
+T 666000000 8MHz 3/4 3/4 QAM64 8k 1/16 NONE
diff --git a/util/scan/dvb-t/pl-Wroclaw b/util/scan/dvb-t/pl-Wroclaw
new file mode 100644
index 0000000..d6b0f9b
--- /dev/null
+++ b/util/scan/dvb-t/pl-Wroclaw
@@ -0,0 +1,3 @@
+# Wroclaw / Zorawina, South-West Poland
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE
diff --git a/util/scan/dvb-t/se-Alvdalen_Brunnsberg b/util/scan/dvb-t/se-Alvdalen_Brunnsberg
new file mode 100644
index 0000000..d9e5427
--- /dev/null
+++ b/util/scan/dvb-t/se-Alvdalen_Brunnsberg
@@ -0,0 +1,3 @@
+# Sweden - Älvdalen/Brunnsberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Alvdalsasen b/util/scan/dvb-t/se-Alvdalsasen
new file mode 100644
index 0000000..d291cf6
--- /dev/null
+++ b/util/scan/dvb-t/se-Alvdalsasen
@@ -0,0 +1,3 @@
+# Sweden - Älvdalsåsen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Alvsbyn b/util/scan/dvb-t/se-Alvsbyn
new file mode 100644
index 0000000..214928d
--- /dev/null
+++ b/util/scan/dvb-t/se-Alvsbyn
@@ -0,0 +1,7 @@
+# Sweden - Älvsbyn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Amot b/util/scan/dvb-t/se-Amot
new file mode 100644
index 0000000..f93453c
--- /dev/null
+++ b/util/scan/dvb-t/se-Amot
@@ -0,0 +1,3 @@
+# Sweden - Ã…mot
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ange_Snoberg b/util/scan/dvb-t/se-Ange_Snoberg
new file mode 100644
index 0000000..661ec98
--- /dev/null
+++ b/util/scan/dvb-t/se-Ange_Snoberg
@@ -0,0 +1,6 @@
+# Sweden - Ånge/Snöberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Angebo b/util/scan/dvb-t/se-Angebo
new file mode 100644
index 0000000..ee67956
--- /dev/null
+++ b/util/scan/dvb-t/se-Angebo
@@ -0,0 +1,3 @@
+# Sweden - Ängebo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Angelholm_Vegeholm b/util/scan/dvb-t/se-Angelholm_Vegeholm
new file mode 100644
index 0000000..fd79bf7
--- /dev/null
+++ b/util/scan/dvb-t/se-Angelholm_Vegeholm
@@ -0,0 +1,7 @@
+# Sweden - Ängelholm/Vegeholm
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 634000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 794000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Arvidsjaur_Jultrask b/util/scan/dvb-t/se-Arvidsjaur_Jultrask
new file mode 100644
index 0000000..4b559b8
--- /dev/null
+++ b/util/scan/dvb-t/se-Arvidsjaur_Jultrask
@@ -0,0 +1,6 @@
+# Sweden - Arvidsjaur/Julträsk
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Aspeboda b/util/scan/dvb-t/se-Aspeboda
new file mode 100644
index 0000000..825b96b
--- /dev/null
+++ b/util/scan/dvb-t/se-Aspeboda
@@ -0,0 +1,3 @@
+# Sweden - Aspeboda
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Atvidaberg b/util/scan/dvb-t/se-Atvidaberg
new file mode 100644
index 0000000..37a7fad
--- /dev/null
+++ b/util/scan/dvb-t/se-Atvidaberg
@@ -0,0 +1,4 @@
+# Sweden - Ã…tvidaberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Avesta_Krylbo b/util/scan/dvb-t/se-Avesta_Krylbo
new file mode 100644
index 0000000..e454a41
--- /dev/null
+++ b/util/scan/dvb-t/se-Avesta_Krylbo
@@ -0,0 +1,4 @@
+# Sweden - Avesta/Krylbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Backefors b/util/scan/dvb-t/se-Backefors
new file mode 100644
index 0000000..d681425
--- /dev/null
+++ b/util/scan/dvb-t/se-Backefors
@@ -0,0 +1,7 @@
+# Sweden - Bäckefors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 586000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 754000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 482000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 826000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Bankeryd b/util/scan/dvb-t/se-Bankeryd
new file mode 100644
index 0000000..06faa37
--- /dev/null
+++ b/util/scan/dvb-t/se-Bankeryd
@@ -0,0 +1,4 @@
+# Sweden - Bankeryd
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bergsjo_Balleberget b/util/scan/dvb-t/se-Bergsjo_Balleberget
new file mode 100644
index 0000000..0c95297
--- /dev/null
+++ b/util/scan/dvb-t/se-Bergsjo_Balleberget
@@ -0,0 +1,3 @@
+# Sweden - Bergsjö/Bålleberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bergvik b/util/scan/dvb-t/se-Bergvik
new file mode 100644
index 0000000..327562d
--- /dev/null
+++ b/util/scan/dvb-t/se-Bergvik
@@ -0,0 +1,3 @@
+# Sweden - Bergvik
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bollebygd b/util/scan/dvb-t/se-Bollebygd
new file mode 100644
index 0000000..155df13
--- /dev/null
+++ b/util/scan/dvb-t/se-Bollebygd
@@ -0,0 +1,4 @@
+# Sweden - Bollebygd
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bollnas b/util/scan/dvb-t/se-Bollnas
new file mode 100644
index 0000000..38eaf1b
--- /dev/null
+++ b/util/scan/dvb-t/se-Bollnas
@@ -0,0 +1,6 @@
+# Sweden - Bollnäs
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 618000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Boras_Dalsjofors b/util/scan/dvb-t/se-Boras_Dalsjofors
new file mode 100644
index 0000000..ea73212
--- /dev/null
+++ b/util/scan/dvb-t/se-Boras_Dalsjofors
@@ -0,0 +1,7 @@
+# Sweden - Borås/Dalsjöfors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 794000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Boras_Sjobo b/util/scan/dvb-t/se-Boras_Sjobo
new file mode 100644
index 0000000..9e1dfe2
--- /dev/null
+++ b/util/scan/dvb-t/se-Boras_Sjobo
@@ -0,0 +1,4 @@
+# Sweden - Borås/Sjöbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 810000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Borlange_Idkerberget b/util/scan/dvb-t/se-Borlange_Idkerberget
new file mode 100644
index 0000000..e30e298
--- /dev/null
+++ b/util/scan/dvb-t/se-Borlange_Idkerberget
@@ -0,0 +1,6 @@
+# Sweden - Borlänge/Idkerberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Borlange_Nygardarna b/util/scan/dvb-t/se-Borlange_Nygardarna
new file mode 100644
index 0000000..c4caad9
--- /dev/null
+++ b/util/scan/dvb-t/se-Borlange_Nygardarna
@@ -0,0 +1,4 @@
+# Sweden - Borlänge/Nygårdarna
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bottnaryd_Ryd b/util/scan/dvb-t/se-Bottnaryd_Ryd
new file mode 100644
index 0000000..88545b4
--- /dev/null
+++ b/util/scan/dvb-t/se-Bottnaryd_Ryd
@@ -0,0 +1,3 @@
+# Sweden - Bottnaryd/Ryd
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bromsebro b/util/scan/dvb-t/se-Bromsebro
new file mode 100644
index 0000000..7dc23bc
--- /dev/null
+++ b/util/scan/dvb-t/se-Bromsebro
@@ -0,0 +1,4 @@
+# Sweden - Brömsebro
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Bruzaholm b/util/scan/dvb-t/se-Bruzaholm
new file mode 100644
index 0000000..d2d82b4
--- /dev/null
+++ b/util/scan/dvb-t/se-Bruzaholm
@@ -0,0 +1,3 @@
+# Sweden - Bruzaholm
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Byxelkrok b/util/scan/dvb-t/se-Byxelkrok
new file mode 100644
index 0000000..280accd
--- /dev/null
+++ b/util/scan/dvb-t/se-Byxelkrok
@@ -0,0 +1,4 @@
+# Sweden - Byxelkrok
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Dadran b/util/scan/dvb-t/se-Dadran
new file mode 100644
index 0000000..6d55531
--- /dev/null
+++ b/util/scan/dvb-t/se-Dadran
@@ -0,0 +1,3 @@
+# Sweden - DÃ¥dran
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Dalfors b/util/scan/dvb-t/se-Dalfors
new file mode 100644
index 0000000..b9f5c76
--- /dev/null
+++ b/util/scan/dvb-t/se-Dalfors
@@ -0,0 +1,3 @@
+# Sweden - Dalfors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Dalstuga b/util/scan/dvb-t/se-Dalstuga
new file mode 100644
index 0000000..d7f5374
--- /dev/null
+++ b/util/scan/dvb-t/se-Dalstuga
@@ -0,0 +1,3 @@
+# Sweden - Dalstuga
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Degerfors b/util/scan/dvb-t/se-Degerfors
new file mode 100644
index 0000000..c0dc0b9
--- /dev/null
+++ b/util/scan/dvb-t/se-Degerfors
@@ -0,0 +1,6 @@
+# Sweden - Degerfors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Delary b/util/scan/dvb-t/se-Delary
new file mode 100644
index 0000000..3c9fdf9
--- /dev/null
+++ b/util/scan/dvb-t/se-Delary
@@ -0,0 +1,3 @@
+# Sweden - Delary
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Djura b/util/scan/dvb-t/se-Djura
new file mode 100644
index 0000000..c532219
--- /dev/null
+++ b/util/scan/dvb-t/se-Djura
@@ -0,0 +1,3 @@
+# Sweden - Djura
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Drevdagen b/util/scan/dvb-t/se-Drevdagen
new file mode 100644
index 0000000..8b331c9
--- /dev/null
+++ b/util/scan/dvb-t/se-Drevdagen
@@ -0,0 +1,3 @@
+# Sweden - Drevdagen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Duvnas b/util/scan/dvb-t/se-Duvnas
new file mode 100644
index 0000000..4fea089
--- /dev/null
+++ b/util/scan/dvb-t/se-Duvnas
@@ -0,0 +1,3 @@
+# Sweden - Duvnäs
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Duvnas_Basna b/util/scan/dvb-t/se-Duvnas_Basna
new file mode 100644
index 0000000..22e0bdf
--- /dev/null
+++ b/util/scan/dvb-t/se-Duvnas_Basna
@@ -0,0 +1,3 @@
+# Sweden - Duvnäs/Bäsna
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Edsbyn b/util/scan/dvb-t/se-Edsbyn
new file mode 100644
index 0000000..a8a3eaa
--- /dev/null
+++ b/util/scan/dvb-t/se-Edsbyn
@@ -0,0 +1,3 @@
+# Sweden - Edsbyn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Emmaboda_Balshult b/util/scan/dvb-t/se-Emmaboda_Balshult
new file mode 100644
index 0000000..0e6a2f8
--- /dev/null
+++ b/util/scan/dvb-t/se-Emmaboda_Balshult
@@ -0,0 +1,6 @@
+# Sweden - Emmaboda/Bälshult
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Enviken b/util/scan/dvb-t/se-Enviken
new file mode 100644
index 0000000..0744d26
--- /dev/null
+++ b/util/scan/dvb-t/se-Enviken
@@ -0,0 +1,4 @@
+# Sweden - Enviken
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Fagersta b/util/scan/dvb-t/se-Fagersta
new file mode 100644
index 0000000..9de6d73
--- /dev/null
+++ b/util/scan/dvb-t/se-Fagersta
@@ -0,0 +1,4 @@
+# Sweden - Fagersta
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Falerum_Centrum b/util/scan/dvb-t/se-Falerum_Centrum
new file mode 100644
index 0000000..36d5496
--- /dev/null
+++ b/util/scan/dvb-t/se-Falerum_Centrum
@@ -0,0 +1,3 @@
+# Sweden - Falerum/Centrum
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Falun_Lovberget b/util/scan/dvb-t/se-Falun_Lovberget
new file mode 100644
index 0000000..8b6cd13
--- /dev/null
+++ b/util/scan/dvb-t/se-Falun_Lovberget
@@ -0,0 +1,6 @@
+# Sweden - Falun/Lövberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Farila b/util/scan/dvb-t/se-Farila
new file mode 100644
index 0000000..b1c1840
--- /dev/null
+++ b/util/scan/dvb-t/se-Farila
@@ -0,0 +1,3 @@
+# Sweden - Färila
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Faro_Ajkerstrask b/util/scan/dvb-t/se-Faro_Ajkerstrask
new file mode 100644
index 0000000..7bdbed7
--- /dev/null
+++ b/util/scan/dvb-t/se-Faro_Ajkerstrask
@@ -0,0 +1,4 @@
+# Sweden - Fårö/Ajkersträsk
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Farosund_Bunge b/util/scan/dvb-t/se-Farosund_Bunge
new file mode 100644
index 0000000..4148e0b
--- /dev/null
+++ b/util/scan/dvb-t/se-Farosund_Bunge
@@ -0,0 +1,7 @@
+# Sweden - Fårösund/Bunge
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Filipstad_Klockarhojden b/util/scan/dvb-t/se-Filipstad_Klockarhojden
new file mode 100644
index 0000000..a30d2ad
--- /dev/null
+++ b/util/scan/dvb-t/se-Filipstad_Klockarhojden
@@ -0,0 +1,6 @@
+# Sweden - Filipstad/Klockarhöjden
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Finnveden b/util/scan/dvb-t/se-Finnveden
new file mode 100644
index 0000000..f577cfd
--- /dev/null
+++ b/util/scan/dvb-t/se-Finnveden
@@ -0,0 +1,6 @@
+# Sweden - Finnveden
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Fredriksberg b/util/scan/dvb-t/se-Fredriksberg
new file mode 100644
index 0000000..3838a7b
--- /dev/null
+++ b/util/scan/dvb-t/se-Fredriksberg
@@ -0,0 +1,3 @@
+# Sweden - Fredriksberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Fritsla b/util/scan/dvb-t/se-Fritsla
new file mode 100644
index 0000000..fd5dc30
--- /dev/null
+++ b/util/scan/dvb-t/se-Fritsla
@@ -0,0 +1,3 @@
+# Sweden - Fritsla
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Furudal b/util/scan/dvb-t/se-Furudal
new file mode 100644
index 0000000..ca847cf
--- /dev/null
+++ b/util/scan/dvb-t/se-Furudal
@@ -0,0 +1,3 @@
+# Sweden - Furudal
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gallivare b/util/scan/dvb-t/se-Gallivare
new file mode 100644
index 0000000..27167ea
--- /dev/null
+++ b/util/scan/dvb-t/se-Gallivare
@@ -0,0 +1,6 @@
+# Sweden - Gällivare
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Garpenberg_Kuppgarden b/util/scan/dvb-t/se-Garpenberg_Kuppgarden
new file mode 100644
index 0000000..bcd7685
--- /dev/null
+++ b/util/scan/dvb-t/se-Garpenberg_Kuppgarden
@@ -0,0 +1,3 @@
+# Sweden - Garpenberg/Kuppgården
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gavle_Skogmur b/util/scan/dvb-t/se-Gavle_Skogmur
new file mode 100644
index 0000000..0a229e7
--- /dev/null
+++ b/util/scan/dvb-t/se-Gavle_Skogmur
@@ -0,0 +1,6 @@
+# Sweden - Gävle/Skogmur
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gnarp b/util/scan/dvb-t/se-Gnarp
new file mode 100644
index 0000000..b47e78a
--- /dev/null
+++ b/util/scan/dvb-t/se-Gnarp
@@ -0,0 +1,3 @@
+# Sweden - Gnarp
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gnesta b/util/scan/dvb-t/se-Gnesta
new file mode 100644
index 0000000..3f1b75c
--- /dev/null
+++ b/util/scan/dvb-t/se-Gnesta
@@ -0,0 +1,4 @@
+# Sweden - Gnesta
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gnosjo_Marieholm b/util/scan/dvb-t/se-Gnosjo_Marieholm
new file mode 100644
index 0000000..ed789ab
--- /dev/null
+++ b/util/scan/dvb-t/se-Gnosjo_Marieholm
@@ -0,0 +1,3 @@
+# Sweden - Gnosjö/Marieholm
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Goteborg_Brudaremossen b/util/scan/dvb-t/se-Goteborg_Brudaremossen
new file mode 100644
index 0000000..80d57a7
--- /dev/null
+++ b/util/scan/dvb-t/se-Goteborg_Brudaremossen
@@ -0,0 +1,7 @@
+# Sweden - Göteborg/Brudaremossen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Goteborg_Slattadamm b/util/scan/dvb-t/se-Goteborg_Slattadamm
new file mode 100644
index 0000000..11ccd75
--- /dev/null
+++ b/util/scan/dvb-t/se-Goteborg_Slattadamm
@@ -0,0 +1,7 @@
+# Sweden - Göteborg/Slättadamm
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gullbrandstorp b/util/scan/dvb-t/se-Gullbrandstorp
new file mode 100644
index 0000000..c407b0d
--- /dev/null
+++ b/util/scan/dvb-t/se-Gullbrandstorp
@@ -0,0 +1,3 @@
+# Sweden - Gullbrandstorp
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gunnarsbo b/util/scan/dvb-t/se-Gunnarsbo
new file mode 100644
index 0000000..d79b851
--- /dev/null
+++ b/util/scan/dvb-t/se-Gunnarsbo
@@ -0,0 +1,3 @@
+# Sweden - Gunnarsbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Gusum b/util/scan/dvb-t/se-Gusum
new file mode 100644
index 0000000..21411cf
--- /dev/null
+++ b/util/scan/dvb-t/se-Gusum
@@ -0,0 +1,3 @@
+# Sweden - Gusum
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hagfors_Varmullsasen b/util/scan/dvb-t/se-Hagfors_Varmullsasen
new file mode 100644
index 0000000..f013fb3
--- /dev/null
+++ b/util/scan/dvb-t/se-Hagfors_Varmullsasen
@@ -0,0 +1,6 @@
+# Sweden - Hagfors/Värmullsåsen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hallaryd b/util/scan/dvb-t/se-Hallaryd
new file mode 100644
index 0000000..5d21d8a
--- /dev/null
+++ b/util/scan/dvb-t/se-Hallaryd
@@ -0,0 +1,3 @@
+# Sweden - Hallaryd
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hallbo b/util/scan/dvb-t/se-Hallbo
new file mode 100644
index 0000000..ed0f8da
--- /dev/null
+++ b/util/scan/dvb-t/se-Hallbo
@@ -0,0 +1,3 @@
+# Sweden - Hällbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Halmstad_Hamnen b/util/scan/dvb-t/se-Halmstad_Hamnen
new file mode 100644
index 0000000..50c88f3
--- /dev/null
+++ b/util/scan/dvb-t/se-Halmstad_Hamnen
@@ -0,0 +1,4 @@
+# Sweden - Halmstad/Hamnen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Halmstad_Oskarstrom b/util/scan/dvb-t/se-Halmstad_Oskarstrom
new file mode 100644
index 0000000..9fc5537
--- /dev/null
+++ b/util/scan/dvb-t/se-Halmstad_Oskarstrom
@@ -0,0 +1,6 @@
+# Sweden - Halmstad/Oskarström
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 530000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 610000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 666000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Harnosand_Harnon b/util/scan/dvb-t/se-Harnosand_Harnon
new file mode 100644
index 0000000..242088e
--- /dev/null
+++ b/util/scan/dvb-t/se-Harnosand_Harnon
@@ -0,0 +1,6 @@
+# Sweden - Härnösand/Härnön
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hassela b/util/scan/dvb-t/se-Hassela
new file mode 100644
index 0000000..7ce0767
--- /dev/null
+++ b/util/scan/dvb-t/se-Hassela
@@ -0,0 +1,3 @@
+# Sweden - Hassela
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Havdhem b/util/scan/dvb-t/se-Havdhem
new file mode 100644
index 0000000..4340063
--- /dev/null
+++ b/util/scan/dvb-t/se-Havdhem
@@ -0,0 +1,7 @@
+# Sweden - Havdhem
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hedemora b/util/scan/dvb-t/se-Hedemora
new file mode 100644
index 0000000..94dc5e3
--- /dev/null
+++ b/util/scan/dvb-t/se-Hedemora
@@ -0,0 +1,3 @@
+# Sweden - Hedemora
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Helsingborg_Olympia b/util/scan/dvb-t/se-Helsingborg_Olympia
new file mode 100644
index 0000000..4358f61
--- /dev/null
+++ b/util/scan/dvb-t/se-Helsingborg_Olympia
@@ -0,0 +1,7 @@
+# Sweden - Helsingborg/Olympia
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 634000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 794000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Hennan b/util/scan/dvb-t/se-Hennan
new file mode 100644
index 0000000..cd1605a
--- /dev/null
+++ b/util/scan/dvb-t/se-Hennan
@@ -0,0 +1,3 @@
+# Sweden - Hennan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hestra_Aspas b/util/scan/dvb-t/se-Hestra_Aspas
new file mode 100644
index 0000000..ae955cc
--- /dev/null
+++ b/util/scan/dvb-t/se-Hestra_Aspas
@@ -0,0 +1,3 @@
+# Sweden - Hestra/Äspås
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hjo_Grevback b/util/scan/dvb-t/se-Hjo_Grevback
new file mode 100644
index 0000000..7045a53
--- /dev/null
+++ b/util/scan/dvb-t/se-Hjo_Grevback
@@ -0,0 +1,3 @@
+# Sweden - Hjo/Grevbäck
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hofors b/util/scan/dvb-t/se-Hofors
new file mode 100644
index 0000000..9314fc1
--- /dev/null
+++ b/util/scan/dvb-t/se-Hofors
@@ -0,0 +1,6 @@
+# Sweden - Hofors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hogfors b/util/scan/dvb-t/se-Hogfors
new file mode 100644
index 0000000..514f1e5
--- /dev/null
+++ b/util/scan/dvb-t/se-Hogfors
@@ -0,0 +1,3 @@
+# Sweden - Högfors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hogsby_Virstad b/util/scan/dvb-t/se-Hogsby_Virstad
new file mode 100644
index 0000000..0cc2ad6
--- /dev/null
+++ b/util/scan/dvb-t/se-Hogsby_Virstad
@@ -0,0 +1,4 @@
+# Sweden - Högsby/Virstad
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Holsbybrunn_Holsbyholm b/util/scan/dvb-t/se-Holsbybrunn_Holsbyholm
new file mode 100644
index 0000000..e5a1d7b
--- /dev/null
+++ b/util/scan/dvb-t/se-Holsbybrunn_Holsbyholm
@@ -0,0 +1,3 @@
+# Sweden - Holsbybrunn/Holsbyholm
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Horby_Sallerup b/util/scan/dvb-t/se-Horby_Sallerup
new file mode 100644
index 0000000..eac745a
--- /dev/null
+++ b/util/scan/dvb-t/se-Horby_Sallerup
@@ -0,0 +1,7 @@
+# Sweden - Hörby/Sallerup
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 634000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 794000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Horken b/util/scan/dvb-t/se-Horken
new file mode 100644
index 0000000..6f3fcdb
--- /dev/null
+++ b/util/scan/dvb-t/se-Horken
@@ -0,0 +1,3 @@
+# Sweden - Hörken
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Hudiksvall_Forsa b/util/scan/dvb-t/se-Hudiksvall_Forsa
new file mode 100644
index 0000000..c8bad49
--- /dev/null
+++ b/util/scan/dvb-t/se-Hudiksvall_Forsa
@@ -0,0 +1,6 @@
+# Sweden - Hudiksvall/Forsa
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 618000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Hudiksvall_Galgberget b/util/scan/dvb-t/se-Hudiksvall_Galgberget
new file mode 100644
index 0000000..b95873e
--- /dev/null
+++ b/util/scan/dvb-t/se-Hudiksvall_Galgberget
@@ -0,0 +1,4 @@
+# Sweden - Hudiksvall/Galgberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Huskvarna b/util/scan/dvb-t/se-Huskvarna
new file mode 100644
index 0000000..2c6a5ca
--- /dev/null
+++ b/util/scan/dvb-t/se-Huskvarna
@@ -0,0 +1,3 @@
+# Sweden - Huskvarna
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Idre b/util/scan/dvb-t/se-Idre
new file mode 100644
index 0000000..912aa70
--- /dev/null
+++ b/util/scan/dvb-t/se-Idre
@@ -0,0 +1,3 @@
+# Sweden - Idre
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ingatorp b/util/scan/dvb-t/se-Ingatorp
new file mode 100644
index 0000000..11d37b5
--- /dev/null
+++ b/util/scan/dvb-t/se-Ingatorp
@@ -0,0 +1,3 @@
+# Sweden - Ingatorp
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ingvallsbenning b/util/scan/dvb-t/se-Ingvallsbenning
new file mode 100644
index 0000000..8726759
--- /dev/null
+++ b/util/scan/dvb-t/se-Ingvallsbenning
@@ -0,0 +1,3 @@
+# Sweden - Ingvallsbenning
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Irevik b/util/scan/dvb-t/se-Irevik
new file mode 100644
index 0000000..1530771
--- /dev/null
+++ b/util/scan/dvb-t/se-Irevik
@@ -0,0 +1,4 @@
+# Sweden - Irevik
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Jamjo b/util/scan/dvb-t/se-Jamjo
new file mode 100644
index 0000000..0c14927
--- /dev/null
+++ b/util/scan/dvb-t/se-Jamjo
@@ -0,0 +1,4 @@
+# Sweden - Jämjö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Jarnforsen b/util/scan/dvb-t/se-Jarnforsen
new file mode 100644
index 0000000..d129f35
--- /dev/null
+++ b/util/scan/dvb-t/se-Jarnforsen
@@ -0,0 +1,3 @@
+# Sweden - Järnforsen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Jarvso b/util/scan/dvb-t/se-Jarvso
new file mode 100644
index 0000000..c779daf
--- /dev/null
+++ b/util/scan/dvb-t/se-Jarvso
@@ -0,0 +1,3 @@
+# Sweden - Järvsö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Jokkmokk_Tjalmejaure b/util/scan/dvb-t/se-Jokkmokk_Tjalmejaure
new file mode 100644
index 0000000..74d4ca3
--- /dev/null
+++ b/util/scan/dvb-t/se-Jokkmokk_Tjalmejaure
@@ -0,0 +1,6 @@
+# Sweden - Jokkmokk/Tjalmejaure
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Jonkoping_Bondberget b/util/scan/dvb-t/se-Jonkoping_Bondberget
new file mode 100644
index 0000000..5c0d21e
--- /dev/null
+++ b/util/scan/dvb-t/se-Jonkoping_Bondberget
@@ -0,0 +1,6 @@
+# Sweden - Jönköping/Bondberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kalix b/util/scan/dvb-t/se-Kalix
new file mode 100644
index 0000000..21a29a8
--- /dev/null
+++ b/util/scan/dvb-t/se-Kalix
@@ -0,0 +1,6 @@
+# Sweden - Kalix
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 770000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 786000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 746000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Karbole b/util/scan/dvb-t/se-Karbole
new file mode 100644
index 0000000..9f28422
--- /dev/null
+++ b/util/scan/dvb-t/se-Karbole
@@ -0,0 +1,3 @@
+# Sweden - Kårböle
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Karlsborg_Vaberget b/util/scan/dvb-t/se-Karlsborg_Vaberget
new file mode 100644
index 0000000..b84b8e8
--- /dev/null
+++ b/util/scan/dvb-t/se-Karlsborg_Vaberget
@@ -0,0 +1,3 @@
+# Sweden - Karlsborg/Vaberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Karlshamn b/util/scan/dvb-t/se-Karlshamn
new file mode 100644
index 0000000..ed3a7cd
--- /dev/null
+++ b/util/scan/dvb-t/se-Karlshamn
@@ -0,0 +1,6 @@
+# Sweden - Karlshamn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 498000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 642000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 522000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Karlskrona_Vamo b/util/scan/dvb-t/se-Karlskrona_Vamo
new file mode 100644
index 0000000..68e38ae
--- /dev/null
+++ b/util/scan/dvb-t/se-Karlskrona_Vamo
@@ -0,0 +1,6 @@
+# Sweden - Karlskrona/Vämö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 498000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 642000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 522000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Karlstad_Sormon b/util/scan/dvb-t/se-Karlstad_Sormon
new file mode 100644
index 0000000..c9cb8e2
--- /dev/null
+++ b/util/scan/dvb-t/se-Karlstad_Sormon
@@ -0,0 +1,9 @@
+# Sweden - Karlstad Sörmon Valid from 2007 09 26. Ver. 2 Correct FEC
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+# Channels
+# Mux3=30
+T 546000000 8MHz 2/3 1/2 QAM64 8k 1/8 NONE
+# Mux4=42
+T 642000000 8MHz 2/3 1/2 QAM64 8k 1/8 NONE
+# Mux1=43
+T 650000000 8MHz 2/3 1/2 QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kaxholmen_Vistakulle b/util/scan/dvb-t/se-Kaxholmen_Vistakulle
new file mode 100644
index 0000000..ede8ad9
--- /dev/null
+++ b/util/scan/dvb-t/se-Kaxholmen_Vistakulle
@@ -0,0 +1,3 @@
+# Sweden - Kaxholmen/Vistakulle
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kinnastrom b/util/scan/dvb-t/se-Kinnastrom
new file mode 100644
index 0000000..61256eb
--- /dev/null
+++ b/util/scan/dvb-t/se-Kinnastrom
@@ -0,0 +1,3 @@
+# Sweden - Kinnaström
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kiruna_Kirunavaara b/util/scan/dvb-t/se-Kiruna_Kirunavaara
new file mode 100644
index 0000000..dac4c24
--- /dev/null
+++ b/util/scan/dvb-t/se-Kiruna_Kirunavaara
@@ -0,0 +1,6 @@
+# Sweden - Kiruna/Kirunavaara
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kisa b/util/scan/dvb-t/se-Kisa
new file mode 100644
index 0000000..21d4bc3
--- /dev/null
+++ b/util/scan/dvb-t/se-Kisa
@@ -0,0 +1,7 @@
+# Sweden - Kisa
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Knared b/util/scan/dvb-t/se-Knared
new file mode 100644
index 0000000..2feda10
--- /dev/null
+++ b/util/scan/dvb-t/se-Knared
@@ -0,0 +1,3 @@
+# Sweden - Knäred
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kopmanholmen b/util/scan/dvb-t/se-Kopmanholmen
new file mode 100644
index 0000000..f9f9541
--- /dev/null
+++ b/util/scan/dvb-t/se-Kopmanholmen
@@ -0,0 +1,6 @@
+# Sweden - Köpmanholmen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kopparberg b/util/scan/dvb-t/se-Kopparberg
new file mode 100644
index 0000000..af84cfe
--- /dev/null
+++ b/util/scan/dvb-t/se-Kopparberg
@@ -0,0 +1,4 @@
+# Sweden - Kopparberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kramfors_Lugnvik b/util/scan/dvb-t/se-Kramfors_Lugnvik
new file mode 100644
index 0000000..f17f8c1
--- /dev/null
+++ b/util/scan/dvb-t/se-Kramfors_Lugnvik
@@ -0,0 +1,6 @@
+# Sweden - Kramfors/Lugnvik
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kristinehamn_Utsiktsberget b/util/scan/dvb-t/se-Kristinehamn_Utsiktsberget
new file mode 100644
index 0000000..71c465d
--- /dev/null
+++ b/util/scan/dvb-t/se-Kristinehamn_Utsiktsberget
@@ -0,0 +1,6 @@
+# Sweden - Kristinehamn/Utsiktsberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 522000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 642000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 626000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Kungsater b/util/scan/dvb-t/se-Kungsater
new file mode 100644
index 0000000..0876dba
--- /dev/null
+++ b/util/scan/dvb-t/se-Kungsater
@@ -0,0 +1,3 @@
+# Sweden - Kungsäter
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Kungsberget_GI b/util/scan/dvb-t/se-Kungsberget_GI
new file mode 100644
index 0000000..0c4eeb3
--- /dev/null
+++ b/util/scan/dvb-t/se-Kungsberget_GI
@@ -0,0 +1,3 @@
+# Sweden - Kungsberget/GI
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Langshyttan b/util/scan/dvb-t/se-Langshyttan
new file mode 100644
index 0000000..bbba370
--- /dev/null
+++ b/util/scan/dvb-t/se-Langshyttan
@@ -0,0 +1,3 @@
+# Sweden - LÃ¥ngshyttan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Langshyttan_Engelsfors b/util/scan/dvb-t/se-Langshyttan_Engelsfors
new file mode 100644
index 0000000..373446a
--- /dev/null
+++ b/util/scan/dvb-t/se-Langshyttan_Engelsfors
@@ -0,0 +1,3 @@
+# Sweden - LÃ¥ngshyttan/Engelsfors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Leksand_Karingberget b/util/scan/dvb-t/se-Leksand_Karingberget
new file mode 100644
index 0000000..2d15561
--- /dev/null
+++ b/util/scan/dvb-t/se-Leksand_Karingberget
@@ -0,0 +1,3 @@
+# Sweden - Leksand/Käringberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Lerdala b/util/scan/dvb-t/se-Lerdala
new file mode 100644
index 0000000..2428c69
--- /dev/null
+++ b/util/scan/dvb-t/se-Lerdala
@@ -0,0 +1,3 @@
+# Sweden - Lerdala
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Lilltjara_Digerberget b/util/scan/dvb-t/se-Lilltjara_Digerberget
new file mode 100644
index 0000000..f2cee9f
--- /dev/null
+++ b/util/scan/dvb-t/se-Lilltjara_Digerberget
@@ -0,0 +1,3 @@
+# Sweden - Lilltjära/Digerberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Limedsforsen b/util/scan/dvb-t/se-Limedsforsen
new file mode 100644
index 0000000..12b36ef
--- /dev/null
+++ b/util/scan/dvb-t/se-Limedsforsen
@@ -0,0 +1,3 @@
+# Sweden - Limedsforsen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Lindshammar_Ramkvilla b/util/scan/dvb-t/se-Lindshammar_Ramkvilla
new file mode 100644
index 0000000..9a03b1e
--- /dev/null
+++ b/util/scan/dvb-t/se-Lindshammar_Ramkvilla
@@ -0,0 +1,3 @@
+# Sweden - Lindshammar/Ramkvilla
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Linkoping_Vattentornet b/util/scan/dvb-t/se-Linkoping_Vattentornet
new file mode 100644
index 0000000..31adae8
--- /dev/null
+++ b/util/scan/dvb-t/se-Linkoping_Vattentornet
@@ -0,0 +1,7 @@
+# Sweden - Linköping/Vattentornet
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ljugarn b/util/scan/dvb-t/se-Ljugarn
new file mode 100644
index 0000000..6474a15
--- /dev/null
+++ b/util/scan/dvb-t/se-Ljugarn
@@ -0,0 +1,4 @@
+# Sweden - Ljugarn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Loffstrand b/util/scan/dvb-t/se-Loffstrand
new file mode 100644
index 0000000..f95de05
--- /dev/null
+++ b/util/scan/dvb-t/se-Loffstrand
@@ -0,0 +1,6 @@
+# Sweden - Loffstrand
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 650000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 762000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 770000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Lonneberga b/util/scan/dvb-t/se-Lonneberga
new file mode 100644
index 0000000..8664ea9
--- /dev/null
+++ b/util/scan/dvb-t/se-Lonneberga
@@ -0,0 +1,4 @@
+# Sweden - Lönneberga
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Lorstrand b/util/scan/dvb-t/se-Lorstrand
new file mode 100644
index 0000000..30867a3
--- /dev/null
+++ b/util/scan/dvb-t/se-Lorstrand
@@ -0,0 +1,3 @@
+# Sweden - Lörstrand
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ludvika_Bjorkasen b/util/scan/dvb-t/se-Ludvika_Bjorkasen
new file mode 100644
index 0000000..07bccd4
--- /dev/null
+++ b/util/scan/dvb-t/se-Ludvika_Bjorkasen
@@ -0,0 +1,4 @@
+# Sweden - Ludvika/Björkåsen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Lumsheden_Trekanten b/util/scan/dvb-t/se-Lumsheden_Trekanten
new file mode 100644
index 0000000..c8a1c9d
--- /dev/null
+++ b/util/scan/dvb-t/se-Lumsheden_Trekanten
@@ -0,0 +1,3 @@
+# Sweden - Lumsheden/Trekanten
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Lycksele_Knaften b/util/scan/dvb-t/se-Lycksele_Knaften
new file mode 100644
index 0000000..05d6469
--- /dev/null
+++ b/util/scan/dvb-t/se-Lycksele_Knaften
@@ -0,0 +1,6 @@
+# Sweden - Lycksele/Knaften
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Mahult b/util/scan/dvb-t/se-Mahult
new file mode 100644
index 0000000..3c45ffa
--- /dev/null
+++ b/util/scan/dvb-t/se-Mahult
@@ -0,0 +1,3 @@
+# Sweden - Mahult
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Malmo_Jagersro b/util/scan/dvb-t/se-Malmo_Jagersro
new file mode 100644
index 0000000..2d0d845
--- /dev/null
+++ b/util/scan/dvb-t/se-Malmo_Jagersro
@@ -0,0 +1,7 @@
+# Sweden - Malmö/Jägersro
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 634000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 794000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Malung b/util/scan/dvb-t/se-Malung
new file mode 100644
index 0000000..fe2b08d
--- /dev/null
+++ b/util/scan/dvb-t/se-Malung
@@ -0,0 +1,4 @@
+# Sweden - Malung
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Mariannelund b/util/scan/dvb-t/se-Mariannelund
new file mode 100644
index 0000000..2ec7cd6
--- /dev/null
+++ b/util/scan/dvb-t/se-Mariannelund
@@ -0,0 +1,3 @@
+# Sweden - Mariannelund
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Markaryd_Hualtet b/util/scan/dvb-t/se-Markaryd_Hualtet
new file mode 100644
index 0000000..941f30c
--- /dev/null
+++ b/util/scan/dvb-t/se-Markaryd_Hualtet
@@ -0,0 +1,4 @@
+# Sweden - Markaryd/Hualtet
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Matfors b/util/scan/dvb-t/se-Matfors
new file mode 100644
index 0000000..d956929
--- /dev/null
+++ b/util/scan/dvb-t/se-Matfors
@@ -0,0 +1,6 @@
+# Sweden - Matfors
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Molnbo_Tallstugan b/util/scan/dvb-t/se-Molnbo_Tallstugan
new file mode 100644
index 0000000..0ad2e03
--- /dev/null
+++ b/util/scan/dvb-t/se-Molnbo_Tallstugan
@@ -0,0 +1,2 @@
+# Sweden - Mölnbo/Tallstugan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
diff --git a/util/scan/dvb-t/se-Molndal_Vasterberget b/util/scan/dvb-t/se-Molndal_Vasterberget
new file mode 100644
index 0000000..8f38e4c
--- /dev/null
+++ b/util/scan/dvb-t/se-Molndal_Vasterberget
@@ -0,0 +1,7 @@
+# Sweden - Mölndal/Västerberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Mora_Eldris b/util/scan/dvb-t/se-Mora_Eldris
new file mode 100644
index 0000000..9b7253c
--- /dev/null
+++ b/util/scan/dvb-t/se-Mora_Eldris
@@ -0,0 +1,6 @@
+# Sweden - Mora/Eldris
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Motala_Ervasteby b/util/scan/dvb-t/se-Motala_Ervasteby
new file mode 100644
index 0000000..4d673f4
--- /dev/null
+++ b/util/scan/dvb-t/se-Motala_Ervasteby
@@ -0,0 +1,7 @@
+# Sweden - Motala/Ervasteby
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Mullsjo_Torestorp b/util/scan/dvb-t/se-Mullsjo_Torestorp
new file mode 100644
index 0000000..264c443
--- /dev/null
+++ b/util/scan/dvb-t/se-Mullsjo_Torestorp
@@ -0,0 +1,4 @@
+# Sweden - Mullsjö/Torestorp
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 850000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Nassjo b/util/scan/dvb-t/se-Nassjo
new file mode 100644
index 0000000..9fe7769
--- /dev/null
+++ b/util/scan/dvb-t/se-Nassjo
@@ -0,0 +1,6 @@
+# Sweden - Nässjö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Navekvarn b/util/scan/dvb-t/se-Navekvarn
new file mode 100644
index 0000000..1016800
--- /dev/null
+++ b/util/scan/dvb-t/se-Navekvarn
@@ -0,0 +1,3 @@
+# Sweden - Nävekvarn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Norrahammar b/util/scan/dvb-t/se-Norrahammar
new file mode 100644
index 0000000..f6ae37d
--- /dev/null
+++ b/util/scan/dvb-t/se-Norrahammar
@@ -0,0 +1,3 @@
+# Sweden - Norrahammar
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Norrkoping_Krokek b/util/scan/dvb-t/se-Norrkoping_Krokek
new file mode 100644
index 0000000..24fed0c
--- /dev/null
+++ b/util/scan/dvb-t/se-Norrkoping_Krokek
@@ -0,0 +1,7 @@
+# Sweden - Norrköping/Krokek
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Norrtalje_Sodra_Bergen b/util/scan/dvb-t/se-Norrtalje_Sodra_Bergen
new file mode 100644
index 0000000..3fb43c6
--- /dev/null
+++ b/util/scan/dvb-t/se-Norrtalje_Sodra_Bergen
@@ -0,0 +1,7 @@
+# Sweden - Norrtälje/Södra Bergen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Nykoping b/util/scan/dvb-t/se-Nykoping
new file mode 100644
index 0000000..848261c
--- /dev/null
+++ b/util/scan/dvb-t/se-Nykoping
@@ -0,0 +1,3 @@
+# Sweden - Nyköping
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Orebro_Lockhyttan b/util/scan/dvb-t/se-Orebro_Lockhyttan
new file mode 100644
index 0000000..22a5d51
--- /dev/null
+++ b/util/scan/dvb-t/se-Orebro_Lockhyttan
@@ -0,0 +1,7 @@
+# Sweden - Örebro/Lockhyttan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ornskoldsvik_As b/util/scan/dvb-t/se-Ornskoldsvik_As
new file mode 100644
index 0000000..e793d70
--- /dev/null
+++ b/util/scan/dvb-t/se-Ornskoldsvik_As
@@ -0,0 +1,6 @@
+# Sweden - Örnsköldsvik/Ås
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Oskarshamn b/util/scan/dvb-t/se-Oskarshamn
new file mode 100644
index 0000000..98e8476
--- /dev/null
+++ b/util/scan/dvb-t/se-Oskarshamn
@@ -0,0 +1,6 @@
+# Sweden - Oskarshamn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ostersund_Brattasen b/util/scan/dvb-t/se-Ostersund_Brattasen
new file mode 100644
index 0000000..c3828f6
--- /dev/null
+++ b/util/scan/dvb-t/se-Ostersund_Brattasen
@@ -0,0 +1,7 @@
+# Sweden - Östersund/Brattåsen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Osthammar_Valo b/util/scan/dvb-t/se-Osthammar_Valo
new file mode 100644
index 0000000..d616927
--- /dev/null
+++ b/util/scan/dvb-t/se-Osthammar_Valo
@@ -0,0 +1,7 @@
+# Sweden - Östhammar/Valö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Overkalix b/util/scan/dvb-t/se-Overkalix
new file mode 100644
index 0000000..91ec2f5
--- /dev/null
+++ b/util/scan/dvb-t/se-Overkalix
@@ -0,0 +1,6 @@
+# Sweden - Överkalix
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 770000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 786000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 746000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Oxberg b/util/scan/dvb-t/se-Oxberg
new file mode 100644
index 0000000..6a61626
--- /dev/null
+++ b/util/scan/dvb-t/se-Oxberg
@@ -0,0 +1,3 @@
+# Sweden - Oxberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Pajala b/util/scan/dvb-t/se-Pajala
new file mode 100644
index 0000000..98b564d
--- /dev/null
+++ b/util/scan/dvb-t/se-Pajala
@@ -0,0 +1,6 @@
+# Sweden - Pajala
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE #Teracom_Mux_2
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE #Teracom_Mux_3
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE #Teracom_Mux_1
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE #Teracom_Mux_4
diff --git a/util/scan/dvb-t/se-Paulistom b/util/scan/dvb-t/se-Paulistom
new file mode 100644
index 0000000..e4abab5
--- /dev/null
+++ b/util/scan/dvb-t/se-Paulistom
@@ -0,0 +1,3 @@
+# Sweden - Paulistöm
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Rattvik b/util/scan/dvb-t/se-Rattvik
new file mode 100644
index 0000000..f8ffe5f
--- /dev/null
+++ b/util/scan/dvb-t/se-Rattvik
@@ -0,0 +1,3 @@
+# Sweden - Rättvik
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Rengsjo b/util/scan/dvb-t/se-Rengsjo
new file mode 100644
index 0000000..7bb743f
--- /dev/null
+++ b/util/scan/dvb-t/se-Rengsjo
@@ -0,0 +1,3 @@
+# Sweden - Rengsjö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Rorbacksnas b/util/scan/dvb-t/se-Rorbacksnas
new file mode 100644
index 0000000..fb45ce7
--- /dev/null
+++ b/util/scan/dvb-t/se-Rorbacksnas
@@ -0,0 +1,3 @@
+# Sweden - Rörbäcksnäs
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sagmyra b/util/scan/dvb-t/se-Sagmyra
new file mode 100644
index 0000000..f68169b
--- /dev/null
+++ b/util/scan/dvb-t/se-Sagmyra
@@ -0,0 +1,3 @@
+# Sweden - SÃ¥gmyra
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Salen b/util/scan/dvb-t/se-Salen
new file mode 100644
index 0000000..3785059
--- /dev/null
+++ b/util/scan/dvb-t/se-Salen
@@ -0,0 +1,3 @@
+# Sweden - Sälen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Salfjallet b/util/scan/dvb-t/se-Salfjallet
new file mode 100644
index 0000000..d271e62
--- /dev/null
+++ b/util/scan/dvb-t/se-Salfjallet
@@ -0,0 +1,3 @@
+# Sweden - Sälfjället
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sarna_Mickeltemplet b/util/scan/dvb-t/se-Sarna_Mickeltemplet
new file mode 100644
index 0000000..09f8809
--- /dev/null
+++ b/util/scan/dvb-t/se-Sarna_Mickeltemplet
@@ -0,0 +1,3 @@
+# Sweden - Särna/Mickeltemplet
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Satila b/util/scan/dvb-t/se-Satila
new file mode 100644
index 0000000..6f8690f
--- /dev/null
+++ b/util/scan/dvb-t/se-Satila
@@ -0,0 +1,3 @@
+# Sweden - Sätila
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Saxdalen b/util/scan/dvb-t/se-Saxdalen
new file mode 100644
index 0000000..0c2db67
--- /dev/null
+++ b/util/scan/dvb-t/se-Saxdalen
@@ -0,0 +1,3 @@
+# Sweden - Saxdalen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Siljansnas_Uvberget b/util/scan/dvb-t/se-Siljansnas_Uvberget
new file mode 100644
index 0000000..a087eaf
--- /dev/null
+++ b/util/scan/dvb-t/se-Siljansnas_Uvberget
@@ -0,0 +1,3 @@
+# Sweden - Siljansnäs/Uvberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Skarstad b/util/scan/dvb-t/se-Skarstad
new file mode 100644
index 0000000..edc1aac
--- /dev/null
+++ b/util/scan/dvb-t/se-Skarstad
@@ -0,0 +1,3 @@
+# Sweden - Skärstad
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Skattungbyn b/util/scan/dvb-t/se-Skattungbyn
new file mode 100644
index 0000000..d5b0a23
--- /dev/null
+++ b/util/scan/dvb-t/se-Skattungbyn
@@ -0,0 +1,3 @@
+# Sweden - Skattungbyn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Skelleftea b/util/scan/dvb-t/se-Skelleftea
new file mode 100644
index 0000000..818beda
--- /dev/null
+++ b/util/scan/dvb-t/se-Skelleftea
@@ -0,0 +1,6 @@
+# Sweden - Skellefteå
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Skene_Nycklarberget b/util/scan/dvb-t/se-Skene_Nycklarberget
new file mode 100644
index 0000000..9070ae8
--- /dev/null
+++ b/util/scan/dvb-t/se-Skene_Nycklarberget
@@ -0,0 +1,3 @@
+# Sweden - Skene/Nycklarberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Skovde b/util/scan/dvb-t/se-Skovde
new file mode 100644
index 0000000..b79f179
--- /dev/null
+++ b/util/scan/dvb-t/se-Skovde
@@ -0,0 +1,7 @@
+# Sweden - Skövde
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Smedjebacken_Uvberget b/util/scan/dvb-t/se-Smedjebacken_Uvberget
new file mode 100644
index 0000000..abe5f66
--- /dev/null
+++ b/util/scan/dvb-t/se-Smedjebacken_Uvberget
@@ -0,0 +1,6 @@
+# Sweden - Smedjebacken/Uvberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Soderhamn b/util/scan/dvb-t/se-Soderhamn
new file mode 100644
index 0000000..a7d6fef
--- /dev/null
+++ b/util/scan/dvb-t/se-Soderhamn
@@ -0,0 +1,4 @@
+# Sweden - Söderhamn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 810000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Soderkoping b/util/scan/dvb-t/se-Soderkoping
new file mode 100644
index 0000000..91ceddf
--- /dev/null
+++ b/util/scan/dvb-t/se-Soderkoping
@@ -0,0 +1,4 @@
+# Sweden - Söderköping
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sodertalje_Ragnhildsborg b/util/scan/dvb-t/se-Sodertalje_Ragnhildsborg
new file mode 100644
index 0000000..31d4886
--- /dev/null
+++ b/util/scan/dvb-t/se-Sodertalje_Ragnhildsborg
@@ -0,0 +1,7 @@
+# Sweden - Södertälje/Ragnhildsborg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 794000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Solleftea_Hallsta b/util/scan/dvb-t/se-Solleftea_Hallsta
new file mode 100644
index 0000000..ed48f90
--- /dev/null
+++ b/util/scan/dvb-t/se-Solleftea_Hallsta
@@ -0,0 +1,6 @@
+# Sweden - Sollefteå/Hallsta
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Solleftea_Multra b/util/scan/dvb-t/se-Solleftea_Multra
new file mode 100644
index 0000000..11ff0a3
--- /dev/null
+++ b/util/scan/dvb-t/se-Solleftea_Multra
@@ -0,0 +1,6 @@
+# Sweden - Sollefteå/Multrå
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sorsjon b/util/scan/dvb-t/se-Sorsjon
new file mode 100644
index 0000000..bead4db
--- /dev/null
+++ b/util/scan/dvb-t/se-Sorsjon
@@ -0,0 +1,3 @@
+# Sweden - Sörsjön
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Stockholm_Marieberg b/util/scan/dvb-t/se-Stockholm_Marieberg
new file mode 100644
index 0000000..1b35b14
--- /dev/null
+++ b/util/scan/dvb-t/se-Stockholm_Marieberg
@@ -0,0 +1,7 @@
+# Sweden - Stockholm/Marieberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Stockholm_Nacka b/util/scan/dvb-t/se-Stockholm_Nacka
new file mode 100644
index 0000000..e13a95e
--- /dev/null
+++ b/util/scan/dvb-t/se-Stockholm_Nacka
@@ -0,0 +1,8 @@
+# Sweden - Stockholm/Nacka
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE # Teracom_Mux_1
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE # Teracom_Mux_2
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE # Teracom_Mux_3
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE # Teracom_Mux_4
+T 746000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE # Teracom_Mux_5
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE # Teracom_Mux_6
diff --git a/util/scan/dvb-t/se-Stora_Skedvi b/util/scan/dvb-t/se-Stora_Skedvi
new file mode 100644
index 0000000..2bcd965
--- /dev/null
+++ b/util/scan/dvb-t/se-Stora_Skedvi
@@ -0,0 +1,3 @@
+# Sweden - Stora Skedvi
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Storfjaten b/util/scan/dvb-t/se-Storfjaten
new file mode 100644
index 0000000..9c9a73b
--- /dev/null
+++ b/util/scan/dvb-t/se-Storfjaten
@@ -0,0 +1,3 @@
+# Sweden - Storfjäten
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Storuman b/util/scan/dvb-t/se-Storuman
new file mode 100644
index 0000000..28092f0
--- /dev/null
+++ b/util/scan/dvb-t/se-Storuman
@@ -0,0 +1,6 @@
+# Sweden - Storuman
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Stromstad b/util/scan/dvb-t/se-Stromstad
new file mode 100644
index 0000000..27a2f75
--- /dev/null
+++ b/util/scan/dvb-t/se-Stromstad
@@ -0,0 +1,7 @@
+# Sweden - Strömstad
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 754000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 554000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 530000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Styrsjobo b/util/scan/dvb-t/se-Styrsjobo
new file mode 100644
index 0000000..2970f41
--- /dev/null
+++ b/util/scan/dvb-t/se-Styrsjobo
@@ -0,0 +1,3 @@
+# Sweden - Styrsjöbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sundborn b/util/scan/dvb-t/se-Sundborn
new file mode 100644
index 0000000..182158b
--- /dev/null
+++ b/util/scan/dvb-t/se-Sundborn
@@ -0,0 +1,3 @@
+# Sweden - Sundborn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sundsbruk b/util/scan/dvb-t/se-Sundsbruk
new file mode 100644
index 0000000..6680751
--- /dev/null
+++ b/util/scan/dvb-t/se-Sundsbruk
@@ -0,0 +1,6 @@
+# Sweden - Sundsbruk
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sundsvall_S_Stadsberget b/util/scan/dvb-t/se-Sundsvall_S_Stadsberget
new file mode 100644
index 0000000..14a4a73
--- /dev/null
+++ b/util/scan/dvb-t/se-Sundsvall_S_Stadsberget
@@ -0,0 +1,7 @@
+# Sweden - Sundsvall/S Stadsberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sunne_Blabarskullen b/util/scan/dvb-t/se-Sunne_Blabarskullen
new file mode 100644
index 0000000..02f8436
--- /dev/null
+++ b/util/scan/dvb-t/se-Sunne_Blabarskullen
@@ -0,0 +1,6 @@
+# Sweden - Sunne/Blåbärskullen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Svartnas b/util/scan/dvb-t/se-Svartnas
new file mode 100644
index 0000000..afcb44c
--- /dev/null
+++ b/util/scan/dvb-t/se-Svartnas
@@ -0,0 +1,3 @@
+# Sweden - Svartnäs
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 642000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Sveg_Brickan b/util/scan/dvb-t/se-Sveg_Brickan
new file mode 100644
index 0000000..ad2683b
--- /dev/null
+++ b/util/scan/dvb-t/se-Sveg_Brickan
@@ -0,0 +1,6 @@
+# Sweden - Sveg/Brickan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Taberg b/util/scan/dvb-t/se-Taberg
new file mode 100644
index 0000000..45a752a
--- /dev/null
+++ b/util/scan/dvb-t/se-Taberg
@@ -0,0 +1,3 @@
+# Sweden - Taberg
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Tandadalen b/util/scan/dvb-t/se-Tandadalen
new file mode 100644
index 0000000..8468db5
--- /dev/null
+++ b/util/scan/dvb-t/se-Tandadalen
@@ -0,0 +1,3 @@
+# Sweden - Tandådalen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Tasjo b/util/scan/dvb-t/se-Tasjo
new file mode 100644
index 0000000..5783f73
--- /dev/null
+++ b/util/scan/dvb-t/se-Tasjo
@@ -0,0 +1,6 @@
+# Sweden - Tåsjö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Tollsjo b/util/scan/dvb-t/se-Tollsjo
new file mode 100644
index 0000000..97389e5
--- /dev/null
+++ b/util/scan/dvb-t/se-Tollsjo
@@ -0,0 +1,3 @@
+# Sweden - Töllsjö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Torsby_Bada b/util/scan/dvb-t/se-Torsby_Bada
new file mode 100644
index 0000000..72ef507
--- /dev/null
+++ b/util/scan/dvb-t/se-Torsby_Bada
@@ -0,0 +1,6 @@
+# Sweden - Torsby/Bada
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 802000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Tranas_Bredkarr b/util/scan/dvb-t/se-Tranas_Bredkarr
new file mode 100644
index 0000000..bf32792
--- /dev/null
+++ b/util/scan/dvb-t/se-Tranas_Bredkarr
@@ -0,0 +1,4 @@
+# Sweden - Tranås/Bredkärr
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Tranemo b/util/scan/dvb-t/se-Tranemo
new file mode 100644
index 0000000..d3bebfd
--- /dev/null
+++ b/util/scan/dvb-t/se-Tranemo
@@ -0,0 +1,3 @@
+# Sweden - Tranemo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Transtrand_Bolheden b/util/scan/dvb-t/se-Transtrand_Bolheden
new file mode 100644
index 0000000..9682a69
--- /dev/null
+++ b/util/scan/dvb-t/se-Transtrand_Bolheden
@@ -0,0 +1,4 @@
+# Sweden - Transtrand/Bolheden
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Traryd_Betas b/util/scan/dvb-t/se-Traryd_Betas
new file mode 100644
index 0000000..72bb264
--- /dev/null
+++ b/util/scan/dvb-t/se-Traryd_Betas
@@ -0,0 +1,4 @@
+# Sweden - Traryd/Betås
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 730000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Trollhattan b/util/scan/dvb-t/se-Trollhattan
new file mode 100644
index 0000000..790963e
--- /dev/null
+++ b/util/scan/dvb-t/se-Trollhattan
@@ -0,0 +1,7 @@
+# Sweden - Trollhättan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 754000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 554000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 530000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Trosa b/util/scan/dvb-t/se-Trosa
new file mode 100644
index 0000000..6b11b6a
--- /dev/null
+++ b/util/scan/dvb-t/se-Trosa
@@ -0,0 +1,4 @@
+# Sweden - Trosa
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Tystberga b/util/scan/dvb-t/se-Tystberga
new file mode 100644
index 0000000..3179648
--- /dev/null
+++ b/util/scan/dvb-t/se-Tystberga
@@ -0,0 +1,3 @@
+# Sweden - Tystberga
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Uddevalla_Herrestad b/util/scan/dvb-t/se-Uddevalla_Herrestad
new file mode 100644
index 0000000..aae5e17
--- /dev/null
+++ b/util/scan/dvb-t/se-Uddevalla_Herrestad
@@ -0,0 +1,7 @@
+# Sweden - Uddevalla/Herrestad
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 754000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 554000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 530000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Ullared b/util/scan/dvb-t/se-Ullared
new file mode 100644
index 0000000..7f5956c
--- /dev/null
+++ b/util/scan/dvb-t/se-Ullared
@@ -0,0 +1,3 @@
+# Sweden - Ullared
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ulricehamn b/util/scan/dvb-t/se-Ulricehamn
new file mode 100644
index 0000000..06413e9
--- /dev/null
+++ b/util/scan/dvb-t/se-Ulricehamn
@@ -0,0 +1,4 @@
+# Sweden - Ulricehamn
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 842000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ulvshyttan_Porjus b/util/scan/dvb-t/se-Ulvshyttan_Porjus
new file mode 100644
index 0000000..f69dbfd
--- /dev/null
+++ b/util/scan/dvb-t/se-Ulvshyttan_Porjus
@@ -0,0 +1,3 @@
+# Sweden - Ulvshyttan/Porjus
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Uppsala_Rickomberga b/util/scan/dvb-t/se-Uppsala_Rickomberga
new file mode 100644
index 0000000..a771e5d
--- /dev/null
+++ b/util/scan/dvb-t/se-Uppsala_Rickomberga
@@ -0,0 +1,3 @@
+# Sweden - Uppsala/Rickomberga
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Uppsala_Vedyxa b/util/scan/dvb-t/se-Uppsala_Vedyxa
new file mode 100644
index 0000000..6bd4db8
--- /dev/null
+++ b/util/scan/dvb-t/se-Uppsala_Vedyxa
@@ -0,0 +1,7 @@
+# Sweden - Uppsala/Vedyxa
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vaddo_Elmsta b/util/scan/dvb-t/se-Vaddo_Elmsta
new file mode 100644
index 0000000..aabc9d6
--- /dev/null
+++ b/util/scan/dvb-t/se-Vaddo_Elmsta
@@ -0,0 +1,4 @@
+# Sweden - Väddö/Elmsta
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 514000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Valdemarsvik b/util/scan/dvb-t/se-Valdemarsvik
new file mode 100644
index 0000000..20b8a8e
--- /dev/null
+++ b/util/scan/dvb-t/se-Valdemarsvik
@@ -0,0 +1,4 @@
+# Sweden - Valdemarsvik
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 794000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vannas_Granlundsberget b/util/scan/dvb-t/se-Vannas_Granlundsberget
new file mode 100644
index 0000000..2ef81d1
--- /dev/null
+++ b/util/scan/dvb-t/se-Vannas_Granlundsberget
@@ -0,0 +1,6 @@
+# Sweden - Vännäs/Granlundsberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 786000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 722000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 754000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 594000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vansbro_Hummelberget b/util/scan/dvb-t/se-Vansbro_Hummelberget
new file mode 100644
index 0000000..1280490
--- /dev/null
+++ b/util/scan/dvb-t/se-Vansbro_Hummelberget
@@ -0,0 +1,3 @@
+# Sweden - Vansbro/Hummelberget
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Varberg_Grimeton b/util/scan/dvb-t/se-Varberg_Grimeton
new file mode 100644
index 0000000..abfdd54
--- /dev/null
+++ b/util/scan/dvb-t/se-Varberg_Grimeton
@@ -0,0 +1,6 @@
+# Sweden - Varberg/Grimeton
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 530000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 610000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 666000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Vasteras_Lillharad b/util/scan/dvb-t/se-Vasteras_Lillharad
new file mode 100644
index 0000000..976bff7
--- /dev/null
+++ b/util/scan/dvb-t/se-Vasteras_Lillharad
@@ -0,0 +1,7 @@
+# Sweden - Västerås/Lillhärad
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 610000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vastervik_Farhult b/util/scan/dvb-t/se-Vastervik_Farhult
new file mode 100644
index 0000000..b57a9d3
--- /dev/null
+++ b/util/scan/dvb-t/se-Vastervik_Farhult
@@ -0,0 +1,6 @@
+# Sweden - Västervik/Fårhult
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 546000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vaxbo b/util/scan/dvb-t/se-Vaxbo
new file mode 100644
index 0000000..4214412
--- /dev/null
+++ b/util/scan/dvb-t/se-Vaxbo
@@ -0,0 +1,3 @@
+# Sweden - Växbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vessigebro b/util/scan/dvb-t/se-Vessigebro
new file mode 100644
index 0000000..56a7e16
--- /dev/null
+++ b/util/scan/dvb-t/se-Vessigebro
@@ -0,0 +1,3 @@
+# Sweden - Vessigebro
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 762000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vetlanda_Nye b/util/scan/dvb-t/se-Vetlanda_Nye
new file mode 100644
index 0000000..540e225
--- /dev/null
+++ b/util/scan/dvb-t/se-Vetlanda_Nye
@@ -0,0 +1,3 @@
+# Sweden - Vetlanda/Nye
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vikmanshyttan b/util/scan/dvb-t/se-Vikmanshyttan
new file mode 100644
index 0000000..1def8f3
--- /dev/null
+++ b/util/scan/dvb-t/se-Vikmanshyttan
@@ -0,0 +1,3 @@
+# Sweden - Vikmanshyttan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Virserum b/util/scan/dvb-t/se-Virserum
new file mode 100644
index 0000000..601a573
--- /dev/null
+++ b/util/scan/dvb-t/se-Virserum
@@ -0,0 +1,6 @@
+# Sweden - Virserum
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 738000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Visby_Follingbo b/util/scan/dvb-t/se-Visby_Follingbo
new file mode 100644
index 0000000..f5ec59d
--- /dev/null
+++ b/util/scan/dvb-t/se-Visby_Follingbo
@@ -0,0 +1,7 @@
+# Sweden - Visby/Follingbo
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 690000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Visby_Hamnen b/util/scan/dvb-t/se-Visby_Hamnen
new file mode 100644
index 0000000..374bcb4
--- /dev/null
+++ b/util/scan/dvb-t/se-Visby_Hamnen
@@ -0,0 +1,7 @@
+# Sweden - Visby/Hamnen
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 522000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 506000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 570000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 586000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Visingso b/util/scan/dvb-t/se-Visingso
new file mode 100644
index 0000000..6be33bd
--- /dev/null
+++ b/util/scan/dvb-t/se-Visingso
@@ -0,0 +1,3 @@
+# Sweden - Visingsö
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 650000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Vislanda_Nydala b/util/scan/dvb-t/se-Vislanda_Nydala
new file mode 100644
index 0000000..5611323
--- /dev/null
+++ b/util/scan/dvb-t/se-Vislanda_Nydala
@@ -0,0 +1,6 @@
+# Sweden - Vislanda/Nydala
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 602000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Voxna b/util/scan/dvb-t/se-Voxna
new file mode 100644
index 0000000..8a37481
--- /dev/null
+++ b/util/scan/dvb-t/se-Voxna
@@ -0,0 +1,3 @@
+# Sweden - Voxna
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/se-Ystad_Metallgatan b/util/scan/dvb-t/se-Ystad_Metallgatan
new file mode 100644
index 0000000..c93c995
--- /dev/null
+++ b/util/scan/dvb-t/se-Ystad_Metallgatan
@@ -0,0 +1,7 @@
+# Sweden - Ystad/Metallgatan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 506000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 634000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 818000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
+T 794000000 8MHz 3/4 NONE QAM64 8k 1/4 NONE
diff --git a/util/scan/dvb-t/se-Yttermalung b/util/scan/dvb-t/se-Yttermalung
new file mode 100644
index 0000000..5262080
--- /dev/null
+++ b/util/scan/dvb-t/se-Yttermalung
@@ -0,0 +1,3 @@
+# Sweden - Yttermalung
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/sk-BanskaBystrica b/util/scan/dvb-t/sk-BanskaBystrica
new file mode 100644
index 0000000..48d3170
--- /dev/null
+++ b/util/scan/dvb-t/sk-BanskaBystrica
@@ -0,0 +1,4 @@
+# DVB-T Banska Bystrica (Banska Bystrica, Slovak Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+T 778000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/sk-Bratislava b/util/scan/dvb-t/sk-Bratislava
new file mode 100644
index 0000000..4924be4
--- /dev/null
+++ b/util/scan/dvb-t/sk-Bratislava
@@ -0,0 +1,4 @@
+# DVB-T Bratislava (Bratislava, Slovak Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+T 834000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/sk-Kosice b/util/scan/dvb-t/sk-Kosice
new file mode 100644
index 0000000..46f7a7e
--- /dev/null
+++ b/util/scan/dvb-t/sk-Kosice
@@ -0,0 +1,4 @@
+# DVB-T Kosice (Kosice, Slovak Republic)
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+
+T 658000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
diff --git a/util/scan/dvb-t/tw-Kaohsiung b/util/scan/dvb-t/tw-Kaohsiung
new file mode 100644
index 0000000..f1eabc9
--- /dev/null
+++ b/util/scan/dvb-t/tw-Kaohsiung
@@ -0,0 +1,6 @@
+# Taiwan - Kaohsiung, southern Taiwan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 545000000 6MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 545000000 6MHz 2/3 NONE QAM16 8k 1/8 NONE
+T 557000000 6MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 557000000 6MHz 2/3 NONE QAM16 8k 1/8 NONE
diff --git a/util/scan/dvb-t/tw-Taipei b/util/scan/dvb-t/tw-Taipei
new file mode 100644
index 0000000..3bba686
--- /dev/null
+++ b/util/scan/dvb-t/tw-Taipei
@@ -0,0 +1,7 @@
+# Taiwan - Taipei, northern Taiwan
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 533000000 6MHz 1/2 NONE QAM16 8k 1/8 NONE
+T 545000000 6MHz 2/3 NONE QAM16 8k 1/8 NONE
+T 557000000 6MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 581000000 6MHz 2/3 NONE QAM16 8k 1/4 NONE
+T 593000000 6MHz 2/3 NONE QAM16 8k 1/4 NONE
diff --git a/util/scan/dvb-t/uk-Aberdare b/util/scan/dvb-t/uk-Aberdare
new file mode 100644
index 0000000..e38aad5
--- /dev/null
+++ b/util/scan/dvb-t/uk-Aberdare
@@ -0,0 +1,10 @@
+# UK, Aberdare
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 562167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 489833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 513833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 570167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Angus b/util/scan/dvb-t/uk-Angus
new file mode 100644
index 0000000..250295d
--- /dev/null
+++ b/util/scan/dvb-t/uk-Angus
@@ -0,0 +1,10 @@
+# UK, Angus
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 850000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 777833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 801833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 753833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 825833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BeaconHill b/util/scan/dvb-t/uk-BeaconHill
new file mode 100644
index 0000000..8d1577d
--- /dev/null
+++ b/util/scan/dvb-t/uk-BeaconHill
@@ -0,0 +1,10 @@
+# UK, Beacon Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 721833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 794167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 770167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 738167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 753833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 818167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Belmont b/util/scan/dvb-t/uk-Belmont
new file mode 100644
index 0000000..fee76db
--- /dev/null
+++ b/util/scan/dvb-t/uk-Belmont
@@ -0,0 +1,10 @@
+# UK, Belmont
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 690000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 850000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 834000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Bilsdale b/util/scan/dvb-t/uk-Bilsdale
new file mode 100644
index 0000000..d05c95f
--- /dev/null
+++ b/util/scan/dvb-t/uk-Bilsdale
@@ -0,0 +1,10 @@
+# UK, Bilsdale
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 474000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 554000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 498167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 522167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BlackHill b/util/scan/dvb-t/uk-BlackHill
index 17eae72..ac8c2c1 100644
--- a/util/scan/dvb-t/uk-BlackHill
+++ b/util/scan/dvb-t/uk-BlackHill
@@ -1,3 +1,10 @@
-# uk BlackHill
+# UK, Black Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 634167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 634167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 682167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 658167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 714167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 746000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 826000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Blaenplwyf b/util/scan/dvb-t/uk-Blaenplwyf
new file mode 100644
index 0000000..35dbade
--- /dev/null
+++ b/util/scan/dvb-t/uk-Blaenplwyf
@@ -0,0 +1,10 @@
+# UK, Blaenplwyf
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 482167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 506167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 562167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 570167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BluebellHill b/util/scan/dvb-t/uk-BluebellHill
new file mode 100644
index 0000000..096d08b
--- /dev/null
+++ b/util/scan/dvb-t/uk-BluebellHill
@@ -0,0 +1,10 @@
+# UK, Bluebell Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 498000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 522000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 665833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 641833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Bressay b/util/scan/dvb-t/uk-Bressay
new file mode 100644
index 0000000..c77bfb0
--- /dev/null
+++ b/util/scan/dvb-t/uk-Bressay
@@ -0,0 +1,10 @@
+# UK, Bressay
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 497833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 521833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 553833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 850000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BrierleyHill b/util/scan/dvb-t/uk-BrierleyHill
new file mode 100644
index 0000000..20b3247
--- /dev/null
+++ b/util/scan/dvb-t/uk-BrierleyHill
@@ -0,0 +1,10 @@
+# UK, Brierley Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 850000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 825833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 753833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 777833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 801833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BristolIlchesterCres b/util/scan/dvb-t/uk-BristolIlchesterCres
new file mode 100644
index 0000000..c84c224
--- /dev/null
+++ b/util/scan/dvb-t/uk-BristolIlchesterCres
@@ -0,0 +1,10 @@
+# UK, Bristol Ilchester Cres.
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 697833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 634167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 658167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 682167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 714167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BristolKingsWeston b/util/scan/dvb-t/uk-BristolKingsWeston
new file mode 100644
index 0000000..e3425ee
--- /dev/null
+++ b/util/scan/dvb-t/uk-BristolKingsWeston
@@ -0,0 +1,10 @@
+# UK, Bristol King's Weston
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 482000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 506000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 530000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 562000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Bromsgrove b/util/scan/dvb-t/uk-Bromsgrove
new file mode 100644
index 0000000..efca587
--- /dev/null
+++ b/util/scan/dvb-t/uk-Bromsgrove
@@ -0,0 +1,10 @@
+# UK, Bromsgrove
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 537833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 569833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 489833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 513833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 545833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-BrougherMountain b/util/scan/dvb-t/uk-BrougherMountain
new file mode 100644
index 0000000..d8ad238
--- /dev/null
+++ b/util/scan/dvb-t/uk-BrougherMountain
@@ -0,0 +1,10 @@
+# UK, Brougher Mountain
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 490167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 514167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 570167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Caldbeck b/util/scan/dvb-t/uk-Caldbeck
new file mode 100644
index 0000000..75f2952
--- /dev/null
+++ b/util/scan/dvb-t/uk-Caldbeck
@@ -0,0 +1,10 @@
+# UK, Caldbeck
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 506000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 490000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 514167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-CaradonHill b/util/scan/dvb-t/uk-CaradonHill
new file mode 100644
index 0000000..90f6eef
--- /dev/null
+++ b/util/scan/dvb-t/uk-CaradonHill
@@ -0,0 +1,10 @@
+# UK, Caradon Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 553833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 690000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 497833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 522000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Carmel b/util/scan/dvb-t/uk-Carmel
new file mode 100644
index 0000000..32372c5
--- /dev/null
+++ b/util/scan/dvb-t/uk-Carmel
@@ -0,0 +1,10 @@
+# UK, Carmel
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 825833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 777833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 801833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 850000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Chatton b/util/scan/dvb-t/uk-Chatton
new file mode 100644
index 0000000..fe42d13
--- /dev/null
+++ b/util/scan/dvb-t/uk-Chatton
@@ -0,0 +1,10 @@
+# UK, Chatton
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 626167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 706167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 650167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 674167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 682167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 714167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Chesterfield b/util/scan/dvb-t/uk-Chesterfield
new file mode 100644
index 0000000..ae6b88f
--- /dev/null
+++ b/util/scan/dvb-t/uk-Chesterfield
@@ -0,0 +1,10 @@
+# UK, Chesterfield
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 626000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 650000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 674000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 706000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 722000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Craigkelly b/util/scan/dvb-t/uk-Craigkelly
new file mode 100644
index 0000000..63bb5d4
--- /dev/null
+++ b/util/scan/dvb-t/uk-Craigkelly
@@ -0,0 +1,10 @@
+# UK, Craigkelly
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 570000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 489833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 513833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-CrystalPalace b/util/scan/dvb-t/uk-CrystalPalace
index 9586b25..fc7e55e 100644
--- a/util/scan/dvb-t/uk-CrystalPalace
+++ b/util/scan/dvb-t/uk-CrystalPalace
@@ -1,3 +1,10 @@
-# Crystal Palace
+# UK, Crystal Palace
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 505833333 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 505833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 481833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 561833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 529833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 537833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Darvel b/util/scan/dvb-t/uk-Darvel
new file mode 100644
index 0000000..4fa6382
--- /dev/null
+++ b/util/scan/dvb-t/uk-Darvel
@@ -0,0 +1,10 @@
+# UK, Darvel
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 481833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 505833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 561833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 529833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Divis b/util/scan/dvb-t/uk-Divis
new file mode 100644
index 0000000..3836375
--- /dev/null
+++ b/util/scan/dvb-t/uk-Divis
@@ -0,0 +1,10 @@
+# UK, Divis
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 538000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 569833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 489833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 513833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 690000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Dover b/util/scan/dvb-t/uk-Dover
new file mode 100644
index 0000000..137b49f
--- /dev/null
+++ b/util/scan/dvb-t/uk-Dover
@@ -0,0 +1,14 @@
+# UK, Dover
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 850000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 794167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 745833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 770167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 785833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+# UK, Dover B
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 618167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Durris b/util/scan/dvb-t/uk-Durris
new file mode 100644
index 0000000..851f0f3
--- /dev/null
+++ b/util/scan/dvb-t/uk-Durris
@@ -0,0 +1,10 @@
+# UK, Durris
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 722167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 713833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 634000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 658000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Eitshal b/util/scan/dvb-t/uk-Eitshal
new file mode 100644
index 0000000..0992656
--- /dev/null
+++ b/util/scan/dvb-t/uk-Eitshal
@@ -0,0 +1,10 @@
+# UK, Eitshal
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 481833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 505833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 529833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 561833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-EmleyMoor b/util/scan/dvb-t/uk-EmleyMoor
new file mode 100644
index 0000000..16df648
--- /dev/null
+++ b/util/scan/dvb-t/uk-EmleyMoor
@@ -0,0 +1,10 @@
+# UK, Emley Moor
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 625833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 649833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 673833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 705833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 697833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Fenham b/util/scan/dvb-t/uk-Fenham
new file mode 100644
index 0000000..f9f3da5
--- /dev/null
+++ b/util/scan/dvb-t/uk-Fenham
@@ -0,0 +1,10 @@
+# UK, Fenham
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 545833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 482167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 506167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 562167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Fenton b/util/scan/dvb-t/uk-Fenton
new file mode 100644
index 0000000..78c7819
--- /dev/null
+++ b/util/scan/dvb-t/uk-Fenton
@@ -0,0 +1,10 @@
+# UK, Fenton
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 577833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 545833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 482167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 506167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 562167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Ferryside b/util/scan/dvb-t/uk-Ferryside
new file mode 100644
index 0000000..2031564
--- /dev/null
+++ b/util/scan/dvb-t/uk-Ferryside
@@ -0,0 +1,8 @@
+# UK, Ferryside
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 545833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 498000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 522000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Guildford b/util/scan/dvb-t/uk-Guildford
new file mode 100644
index 0000000..a5350a0
--- /dev/null
+++ b/util/scan/dvb-t/uk-Guildford
@@ -0,0 +1,10 @@
+# UK, Guildford
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 697833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 658167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 634167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 714167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 682167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 738000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Hannington b/util/scan/dvb-t/uk-Hannington
index 0bbbfdd..30a261a 100644
--- a/util/scan/dvb-t/uk-Hannington
+++ b/util/scan/dvb-t/uk-Hannington
@@ -1,3 +1,10 @@
-# Hannington, North Hampshire
+# UK, Hannington
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 706000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 650167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 626167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 674167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 658167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 634167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Hastings b/util/scan/dvb-t/uk-Hastings
new file mode 100644
index 0000000..f5f7b71
--- /dev/null
+++ b/util/scan/dvb-t/uk-Hastings
@@ -0,0 +1,10 @@
+# UK, Hastings
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 553833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 521833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 474000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 497833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 810000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Heathfield b/util/scan/dvb-t/uk-Heathfield
new file mode 100644
index 0000000..b65db77
--- /dev/null
+++ b/util/scan/dvb-t/uk-Heathfield
@@ -0,0 +1,10 @@
+# UK, Heathfield
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 689833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 681833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 738000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 713833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-HemelHempstead b/util/scan/dvb-t/uk-HemelHempstead
new file mode 100644
index 0000000..87fbe86
--- /dev/null
+++ b/util/scan/dvb-t/uk-HemelHempstead
@@ -0,0 +1,10 @@
+# UK, Hemel Hempstead
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 746000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 786167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 777833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 802000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 826000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-HuntshawCross b/util/scan/dvb-t/uk-HuntshawCross
new file mode 100644
index 0000000..9572b29
--- /dev/null
+++ b/util/scan/dvb-t/uk-HuntshawCross
@@ -0,0 +1,13 @@
+# UK, Huntshaw Cross
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 737833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 769833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 793833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 817833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 729833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 761833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+# UK, Huntshaw Cross B
+T 714000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 682000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Idle b/util/scan/dvb-t/uk-Idle
new file mode 100644
index 0000000..84fdc29
--- /dev/null
+++ b/util/scan/dvb-t/uk-Idle
@@ -0,0 +1,10 @@
+# UK, Idle
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 730000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 578000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 754000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 545833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-KeelylangHill b/util/scan/dvb-t/uk-KeelylangHill
new file mode 100644
index 0000000..3b17375
--- /dev/null
+++ b/util/scan/dvb-t/uk-KeelylangHill
@@ -0,0 +1,10 @@
+# UK, Keelylang Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 722167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 634167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 658167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 682167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 714167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Keighley b/util/scan/dvb-t/uk-Keighley
new file mode 100644
index 0000000..7db30f4
--- /dev/null
+++ b/util/scan/dvb-t/uk-Keighley
@@ -0,0 +1,10 @@
+# UK, Keighley
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 690000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 850000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 834000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 729833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-KilveyHill b/util/scan/dvb-t/uk-KilveyHill
new file mode 100644
index 0000000..a091be6
--- /dev/null
+++ b/util/scan/dvb-t/uk-KilveyHill
@@ -0,0 +1,10 @@
+# UK, Kilvey Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 505833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 481833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 529833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 561833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 553833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-KnockMore b/util/scan/dvb-t/uk-KnockMore
new file mode 100644
index 0000000..f6ecb3c
--- /dev/null
+++ b/util/scan/dvb-t/uk-KnockMore
@@ -0,0 +1,10 @@
+# UK, Knock More
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 730000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 762167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 753833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Lancaster b/util/scan/dvb-t/uk-Lancaster
new file mode 100644
index 0000000..69b6129
--- /dev/null
+++ b/util/scan/dvb-t/uk-Lancaster
@@ -0,0 +1,10 @@
+# UK, Lancaster
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 482167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 506167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 562167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 545833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-LarkStoke b/util/scan/dvb-t/uk-LarkStoke
new file mode 100644
index 0000000..a7b7a39
--- /dev/null
+++ b/util/scan/dvb-t/uk-LarkStoke
@@ -0,0 +1,10 @@
+# UK, Lark Stoke
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 554000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 498167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 522167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Limavady b/util/scan/dvb-t/uk-Limavady
new file mode 100644
index 0000000..327d318
--- /dev/null
+++ b/util/scan/dvb-t/uk-Limavady
@@ -0,0 +1,10 @@
+# UK, Limavady
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 842000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 769833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 730000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 761833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 810167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Llanddona b/util/scan/dvb-t/uk-Llanddona
new file mode 100644
index 0000000..123c6be
--- /dev/null
+++ b/util/scan/dvb-t/uk-Llanddona
@@ -0,0 +1,10 @@
+# UK, Llanddona
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 706000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 738167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 770167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 794167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 818167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 674000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Malvern b/util/scan/dvb-t/uk-Malvern
new file mode 100644
index 0000000..da02f7b
--- /dev/null
+++ b/util/scan/dvb-t/uk-Malvern
@@ -0,0 +1,10 @@
+# UK, Malvern
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 682000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 658000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 714000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 634000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Mendip b/util/scan/dvb-t/uk-Mendip
new file mode 100644
index 0000000..966d01f
--- /dev/null
+++ b/util/scan/dvb-t/uk-Mendip
@@ -0,0 +1,10 @@
+# UK, Mendip
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 778167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 746167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 802167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 826167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 754167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 842000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Midhurst b/util/scan/dvb-t/uk-Midhurst
new file mode 100644
index 0000000..c1a5ceb
--- /dev/null
+++ b/util/scan/dvb-t/uk-Midhurst
@@ -0,0 +1,10 @@
+# UK, Midhurst
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 754167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 826167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 802167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 778167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 817833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Moel-y-Parc b/util/scan/dvb-t/uk-Moel-y-Parc
new file mode 100644
index 0000000..94e4997
--- /dev/null
+++ b/util/scan/dvb-t/uk-Moel-y-Parc
@@ -0,0 +1,10 @@
+# UK, Moel-y-Parc
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 738000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 770000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 794000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 818000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Nottingham b/util/scan/dvb-t/uk-Nottingham
new file mode 100644
index 0000000..e94f1c4
--- /dev/null
+++ b/util/scan/dvb-t/uk-Nottingham
@@ -0,0 +1,10 @@
+# UK, Nottingham
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 842000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 730000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 810000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 778000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-OliversMount b/util/scan/dvb-t/uk-OliversMount
new file mode 100644
index 0000000..1ad0017
--- /dev/null
+++ b/util/scan/dvb-t/uk-OliversMount
@@ -0,0 +1,10 @@
+# UK, Oliver's Mount
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 842167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 738167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 770167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 794167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 818167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Oxford b/util/scan/dvb-t/uk-Oxford
index 035603e..744a3d4 100644
--- a/util/scan/dvb-t/uk-Oxford
+++ b/util/scan/dvb-t/uk-Oxford
@@ -1,3 +1,10 @@
-# Oxford
+# UK, Oxford
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 578000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 850000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 713833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 721833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 690000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-PendleForest b/util/scan/dvb-t/uk-PendleForest
new file mode 100644
index 0000000..70d21cc
--- /dev/null
+++ b/util/scan/dvb-t/uk-PendleForest
@@ -0,0 +1,10 @@
+# UK, Pendle Forest
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 497833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 521833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 553833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 545833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Plympton b/util/scan/dvb-t/uk-Plympton
new file mode 100644
index 0000000..c8c30a8
--- /dev/null
+++ b/util/scan/dvb-t/uk-Plympton
@@ -0,0 +1,10 @@
+# UK, Plympton
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 842167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 833833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 785833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 809833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 754000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-PontopPike b/util/scan/dvb-t/uk-PontopPike
index c24ba92..af1f6a5 100644
--- a/util/scan/dvb-t/uk-PontopPike
+++ b/util/scan/dvb-t/uk-PontopPike
@@ -1,3 +1,10 @@
-# Pontop Pike, UK
+# UK, Pontop Pike
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 690000000 8MHz 1/2 NONE QAM16 2k 1/32 NONE
+T 690000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 746167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 778167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 802167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 826167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 729833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Pontypool b/util/scan/dvb-t/uk-Pontypool
new file mode 100644
index 0000000..c258ce8
--- /dev/null
+++ b/util/scan/dvb-t/uk-Pontypool
@@ -0,0 +1,10 @@
+# UK, Pontypool
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 722000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 690000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 642000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 482167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Presely b/util/scan/dvb-t/uk-Presely
new file mode 100644
index 0000000..bdfe4f1
--- /dev/null
+++ b/util/scan/dvb-t/uk-Presely
@@ -0,0 +1,10 @@
+# UK, Presely
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 714167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 618000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 641833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 665833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 697833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Redruth b/util/scan/dvb-t/uk-Redruth
index 84dcb9a..e8285a5 100644
--- a/util/scan/dvb-t/uk-Redruth
+++ b/util/scan/dvb-t/uk-Redruth
@@ -1,3 +1,10 @@
-# Redruth, Cornwall
+# UK, Redruth
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 666167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 697833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 650167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 705833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Reigate b/util/scan/dvb-t/uk-Reigate
index add0d8b..dd40fbf 100644
--- a/util/scan/dvb-t/uk-Reigate
+++ b/util/scan/dvb-t/uk-Reigate
@@ -1,3 +1,10 @@
-# Reigate
+# UK, Reigate
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 554000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 554000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 474000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 498000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 522000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-RidgeHill b/util/scan/dvb-t/uk-RidgeHill
new file mode 100644
index 0000000..40e13f4
--- /dev/null
+++ b/util/scan/dvb-t/uk-RidgeHill
@@ -0,0 +1,10 @@
+# UK, Ridge Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 786000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 810000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Rosemarkie b/util/scan/dvb-t/uk-Rosemarkie
new file mode 100644
index 0000000..36df581
--- /dev/null
+++ b/util/scan/dvb-t/uk-Rosemarkie
@@ -0,0 +1,10 @@
+# UK, Rosemarkie
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 714167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 633833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 657833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 674167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 706167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Rosneath b/util/scan/dvb-t/uk-Rosneath
new file mode 100644
index 0000000..facbd5c
--- /dev/null
+++ b/util/scan/dvb-t/uk-Rosneath
@@ -0,0 +1,10 @@
+# UK, Rosneath
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 842000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 729833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 761833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 785833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 809833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 690000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Rowridge b/util/scan/dvb-t/uk-Rowridge
index c0c72a0..078d7a1 100644
--- a/util/scan/dvb-t/uk-Rowridge
+++ b/util/scan/dvb-t/uk-Rowridge
@@ -1,3 +1,10 @@
-# Rowridge, Isle of Wight
+# UK, Rowridge
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 489833333 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 489833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 530000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 545833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 562167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 513833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 570167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-RumsterForest b/util/scan/dvb-t/uk-RumsterForest
new file mode 100644
index 0000000..87941b3
--- /dev/null
+++ b/util/scan/dvb-t/uk-RumsterForest
@@ -0,0 +1,10 @@
+# UK, Rumster Forest
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 530167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 482167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 506167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 562167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 802000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 778000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Saddleworth b/util/scan/dvb-t/uk-Saddleworth
new file mode 100644
index 0000000..dbd037c
--- /dev/null
+++ b/util/scan/dvb-t/uk-Saddleworth
@@ -0,0 +1,10 @@
+# UK, Saddleworth
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 682000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 633833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 657833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 713833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 738000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Salisbury b/util/scan/dvb-t/uk-Salisbury
new file mode 100644
index 0000000..87b1c1d
--- /dev/null
+++ b/util/scan/dvb-t/uk-Salisbury
@@ -0,0 +1,10 @@
+# UK, Salisbury
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 745833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 753833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 777833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 801833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 826000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 721833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-SandyHeath b/util/scan/dvb-t/uk-SandyHeath
index 05d0474..8c6cf74 100644
--- a/util/scan/dvb-t/uk-SandyHeath
+++ b/util/scan/dvb-t/uk-SandyHeath
@@ -1,3 +1,10 @@
-# Sandy Heath
+# UK, Sandy Heath
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 641833334 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 641833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 665833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 650167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 842000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 626167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 674167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Selkirk b/util/scan/dvb-t/uk-Selkirk
new file mode 100644
index 0000000..88f5f84
--- /dev/null
+++ b/util/scan/dvb-t/uk-Selkirk
@@ -0,0 +1,10 @@
+# UK, Selkirk
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 730167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 786167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 810167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 754167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Sheffield b/util/scan/dvb-t/uk-Sheffield
new file mode 100644
index 0000000..2469611
--- /dev/null
+++ b/util/scan/dvb-t/uk-Sheffield
@@ -0,0 +1,10 @@
+# UK, Sheffield
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 730000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 762000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 786000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-StocklandHill b/util/scan/dvb-t/uk-StocklandHill
new file mode 100644
index 0000000..c0d3c3e
--- /dev/null
+++ b/util/scan/dvb-t/uk-StocklandHill
@@ -0,0 +1,10 @@
+# UK, Stockland Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 481833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 529833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 505833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 561833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 546167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Storeton b/util/scan/dvb-t/uk-Storeton
index 5c93ee9..1ca0841 100644
--- a/util/scan/dvb-t/uk-Storeton
+++ b/util/scan/dvb-t/uk-Storeton
@@ -1,3 +1,10 @@
-# Storeton, Wirral
+# UK, Storeton
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 546167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 490167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 514167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 538167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 570167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Sudbury b/util/scan/dvb-t/uk-Sudbury
new file mode 100644
index 0000000..15e5e23
--- /dev/null
+++ b/util/scan/dvb-t/uk-Sudbury
@@ -0,0 +1,12 @@
+# UK, Sudbury
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 850000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 690167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 738000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 706167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+# UK, Sudbury B
+T 754000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-SuttonColdfield b/util/scan/dvb-t/uk-SuttonColdfield
new file mode 100644
index 0000000..67cf07f
--- /dev/null
+++ b/util/scan/dvb-t/uk-SuttonColdfield
@@ -0,0 +1,10 @@
+# UK, Sutton Coldfield
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 634167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 658167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 682167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 714167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 722167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 746000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Tacolneston b/util/scan/dvb-t/uk-Tacolneston
new file mode 100644
index 0000000..b062cca
--- /dev/null
+++ b/util/scan/dvb-t/uk-Tacolneston
@@ -0,0 +1,10 @@
+# UK, Tacolneston
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 810000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 730167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 769833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 794000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 818000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-TheWrekin b/util/scan/dvb-t/uk-TheWrekin
new file mode 100644
index 0000000..435741c
--- /dev/null
+++ b/util/scan/dvb-t/uk-TheWrekin
@@ -0,0 +1,15 @@
+# UK, The Wrekin
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 554000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 498167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 522167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 730000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 762000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+# UK, The Wrekin B
+T 618167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 698000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 642000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Torosay b/util/scan/dvb-t/uk-Torosay
new file mode 100644
index 0000000..77af3c6
--- /dev/null
+++ b/util/scan/dvb-t/uk-Torosay
@@ -0,0 +1,10 @@
+# UK, Torosay
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 490167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 514167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 538167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 570167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 474000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 553833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-TunbridgeWells b/util/scan/dvb-t/uk-TunbridgeWells
new file mode 100644
index 0000000..6f57c1b
--- /dev/null
+++ b/util/scan/dvb-t/uk-TunbridgeWells
@@ -0,0 +1,10 @@
+# UK, Tunbridge Wells
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 746000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 794000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 642167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 666167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 778000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Waltham b/util/scan/dvb-t/uk-Waltham
new file mode 100644
index 0000000..bc4ab0e
--- /dev/null
+++ b/util/scan/dvb-t/uk-Waltham
@@ -0,0 +1,10 @@
+# UK, Waltham
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 698000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 490000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 514000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 570000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 666000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 642000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-Wenvoe b/util/scan/dvb-t/uk-Wenvoe
new file mode 100644
index 0000000..011c524
--- /dev/null
+++ b/util/scan/dvb-t/uk-Wenvoe
@@ -0,0 +1,10 @@
+# UK, Wenvoe
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 546000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 578000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 625833000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 705833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 649833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 673833000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-WhitehawkHill b/util/scan/dvb-t/uk-WhitehawkHill
new file mode 100644
index 0000000..0d343c3
--- /dev/null
+++ b/util/scan/dvb-t/uk-WhitehawkHill
@@ -0,0 +1,10 @@
+# UK, Whitehawk Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
+# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
+T 834000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 706000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 746000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 690000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 770167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 794167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/dvb-t/uk-WinterHill b/util/scan/dvb-t/uk-WinterHill
index b000623..3ea6abd 100644
--- a/util/scan/dvb-t/uk-WinterHill
+++ b/util/scan/dvb-t/uk-WinterHill
@@ -1,3 +1,13 @@
-# Winter Hill, North-West England
+# UK, Winter Hill
+# Auto-generated from http://www.dtg.org.uk/retailer/dtt_channels.html
+# and http://www.ofcom.org.uk/static/reception_advice/index.asp.html
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
-T 754166670 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 754167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 834167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 850167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE
+T 842167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 786167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 810167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+# UK, Winter Hill B
+T 650000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
+T 626000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE
diff --git a/util/scan/list.h b/util/scan/list.h
index 6032c22..931df96 100644
--- a/util/scan/list.h
+++ b/util/scan/list.h
@@ -26,7 +26,7 @@ struct list_head {
} while (0)
/*
- * Insert a new entry between two known consecutive entries.
+ * Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
@@ -98,7 +98,7 @@ static __inline__ void list_del(struct list_head *entry)
static __inline__ void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
+ INIT_LIST_HEAD(entry);
}
/**
@@ -126,7 +126,7 @@ static __inline__ int list_empty(struct list_head *head)
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
-
+
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
diff --git a/util/scan/lnb.c b/util/scan/lnb.c
index e30c1d6..d0fdf1d 100644
--- a/util/scan/lnb.c
+++ b/util/scan/lnb.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <linux/types.h>
#include "lnb.h"
static char *univ_desc[] = {
diff --git a/util/scan/lnb.h b/util/scan/lnb.h
index f78b7a6..6370fd4 100644
--- a/util/scan/lnb.h
+++ b/util/scan/lnb.h
@@ -1,4 +1,3 @@
-
struct lnb_types_st {
char *name;
char **desc;
@@ -21,4 +20,3 @@ lnb_enum(int curno);
int
lnb_decode(char *str, struct lnb_types_st *lnbp);
-
diff --git a/util/scan/scan.c b/util/scan/scan.c
index 350d9c9..1b7a3e5 100644
--- a/util/scan/scan.c
+++ b/util/scan/scan.c
@@ -61,9 +61,9 @@ static int vdr_dump_provider;
static int vdr_dump_channum;
static int no_ATSC_PSIP;
static int ATSC_type=1;
-static int ca_select = 1;
+static int ca_select = -1;
static int serv_select = 7;
-static int vdr_version = 2;
+static int vdr_version = 3;
static struct lnb_types_st lnb_type;
static int unique_anon_services;
@@ -130,6 +130,7 @@ struct transponder {
struct list_head list;
struct list_head services;
int network_id;
+ int original_network_id;
int transport_stream_id;
enum fe_type type;
struct dvb_frontend_parameters param;
@@ -236,6 +237,7 @@ static struct transponder *find_transponder(uint32_t frequency)
static void copy_transponder(struct transponder *d, struct transponder *s)
{
d->network_id = s->network_id;
+ d->original_network_id = s->original_network_id;
d->transport_stream_id = s->transport_stream_id;
d->type = s->type;
memcpy(&d->param, &s->param, sizeof(d->param));
@@ -755,12 +757,15 @@ static void parse_pmt (const unsigned char *buf, int section_length, int service
switch (buf[0]) {
case 0x01:
case 0x02:
+ case 0x1b: /* H.264 video stream */
moreverbose(" VIDEO : PID 0x%04x\n", elementary_pid);
if (s->video_pid == 0)
s->video_pid = elementary_pid;
break;
case 0x03:
case 0x81: /* Audio per ATSC A/53B [2] Annex B */
+ case 0x0f: /* ADTS Audio Stream - usually AAC */
+ case 0x11: /* ISO/IEC 14496-3 Audio with LATM transport */
case 0x04:
moreverbose(" AUDIO : PID 0x%04x\n", elementary_pid);
if (s->audio_num < AUDIO_CHAN_MAX) {
@@ -772,6 +777,12 @@ static void parse_pmt (const unsigned char *buf, int section_length, int service
warning("more than %i audio channels, truncating\n",
AUDIO_CHAN_MAX);
break;
+ case 0x07:
+ moreverbose(" MHEG : PID 0x%04x\n", elementary_pid);
+ break;
+ case 0x0B:
+ moreverbose(" DSM-CC : PID 0x%04x\n", elementary_pid);
+ break;
case 0x06:
if (find_descriptor(0x56, buf + 5, ES_info_len, NULL, NULL)) {
moreverbose(" TELETEXT : PID 0x%04x\n", elementary_pid);
@@ -860,6 +871,7 @@ static void parse_nit (const unsigned char *buf, int section_length, int network
memset(&tn, 0, sizeof(tn));
tn.type = -1;
tn.network_id = network_id;
+ tn.original_network_id = (buf[2] << 8) | buf[3];
tn.transport_stream_id = transport_stream_id;
parse_descriptors (NIT, buf + 6, descriptors_loop_len, &tn);
@@ -1462,21 +1474,34 @@ static int __tune_to_transponder (int frontend_fd, struct transponder *t)
}
if (t->type == FE_QPSK) {
- int hiband = 0;
-
- if (lnb_type.switch_val && lnb_type.high_val &&
- p.frequency >= lnb_type.switch_val)
- hiband = 1;
-
- setup_switch (frontend_fd,
- switch_pos,
- t->polarisation == POLARISATION_VERTICAL ? 0 : 1,
- hiband);
- usleep(50000);
- if (hiband)
- p.frequency = abs(p.frequency - lnb_type.high_val);
- else
+ if (lnb_type.high_val) {
+ if (lnb_type.switch_val) {
+ /* Voltage-controlled switch */
+ int hiband = 0;
+
+ if (p.frequency >= lnb_type.switch_val)
+ hiband = 1;
+
+ setup_switch (frontend_fd,
+ switch_pos,
+ t->polarisation == POLARISATION_VERTICAL ? 0 : 1,
+ hiband);
+ usleep(50000);
+ if (hiband)
+ p.frequency = abs(p.frequency - lnb_type.high_val);
+ else
+ p.frequency = abs(p.frequency - lnb_type.low_val);
+ } else {
+ /* C-Band Multipoint LNBf */
+ p.frequency = abs(p.frequency - (t->polarisation == POLARISATION_VERTICAL ?
+ lnb_type.low_val: lnb_type.high_val));
+ }
+ } else {
+ /* Monopoint LNBf without switch */
p.frequency = abs(p.frequency - lnb_type.low_val);
+ }
+ if (verbosity >= 2)
+ dprintf(1,"DVB-S IF freq is %d\n",p.frequency);
}
if (ioctl(frontend_fd, FE_SET_FRONTEND, &p) == -1) {
@@ -1991,7 +2016,7 @@ static void dump_lists (void)
//FIXME: s->subtitling_pid
s->ac3_pid,
s->service_id,
- t->network_id,
+ t->original_network_id,
s->transport_stream_id,
t->orbital_pos,
t->we_flag,
@@ -2066,14 +2091,15 @@ static const char *usage = "\n"
" -5 multiply all filter timeouts by factor 5\n"
" for non-DVB-compliant section repitition rates\n"
" -o fmt output format: 'zap' (default), 'vdr' or 'pids' (default with -c)\n"
- " -x N Conditional Axcess, (default 1)\n"
+ " -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"
- " -e N VDR version, default 2 for VDR-1.2.x\n"
- " ANYTHING ELSE GIVES NONZERO NIT and TID\n"
+ " -e N VDR version, default 3 for VDR-1.3.x and newer\n"
+ " value 2 sets NIT and TID to zero\n"
" Vdr version 1.3.x and up implies -p.\n"
" -l lnb-type (DVB-S Only) (use -l help to print types) or \n"
" -l low[,high[,switch]] in Mhz\n"
diff --git a/util/scan/scan.h b/util/scan/scan.h
index 8209076..6ccf6fc 100644
--- a/util/scan/scan.h
+++ b/util/scan/scan.h
@@ -26,4 +26,3 @@ extern int verbosity;
#define verbosedebug(msg...) dpprintf(6, msg)
#endif
-
diff --git a/util/scan/section_generate.pl b/util/scan/section_generate.pl
new file mode 100644
index 0000000..2080dbb
--- /dev/null
+++ b/util/scan/section_generate.pl
@@ -0,0 +1,92 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+die "no section perl file given" unless @ARGV;
+
+my $h = require($ARGV[0]);
+
+our $basename;
+our $debug = $ARGV[1];
+
+($basename) = $ARGV[0] =~ /([a-zA-Z0-9_\-_]+).pl/;
+
+local *H;
+local *C;
+
+h_header();
+c_header();
+
+foreach (sort keys %{$h}) {
+ foreach my $item (@{$h->{$_}}) {
+ if ($_ eq "descriptors") {
+ printf H ("#define %s_ID 0x%02X\n",uc($item->{name}),$item->{id});
+ }
+
+ do_it ($item->{name},$item->{elements});
+ }
+}
+
+h_footer();
+c_footer();
+
+sub type
+{
+ if ($_[0] > 16) {
+ return "u32";
+ } elsif ($_[0] > 8) {
+ return "u16";
+ } else {
+ return "u8 ";
+ }
+}
+
+sub do_it
+{
+ my ($name,$val) = @_;
+ print H "struct $name {\n";
+
+ print C <<EOL;
+struct $name read_$name(const u8 *b)
+{
+ struct $name v;
+EOL
+ my $offs = 0;
+ for (my $i = 0; $i < scalar @{$val}; $i+=2) {
+ printf H ("\t\t%s %-25s :%2d;\n",type($val->[$i+1]),$val->[$i],$val->[$i+1]);
+
+ printf C ("\tv.%-25s = getBits(b,%3d,%2d);\n",$val->[$i],$offs,$val->[$i+1]);
+ printf C ("\tfprintf(stderr,\" %s = %%x %%d\\n\",v.%s,v.%s);\n",$val->[$i],$val->[$i],$val->[$i]) if $debug;
+ $offs += $val->[$i+1];
+ }
+ print H "} PACKED;\n";
+ print H "struct $name read_$name(const u8 *);\n\n";
+
+ print C "\treturn v;\n}\n\n"
+}
+
+sub h_header
+{
+ open(H,">$basename.h");
+ print H "#ifndef __".uc($basename)."_H_\n";
+ print H "#define __".uc($basename)."_H_\n\n";
+ print H "#include \"section.h\"\n\n";
+}
+
+sub c_header
+{
+ open(C,">$basename.c");
+ print C "#include \"$basename.h\"\n\n";
+}
+
+
+sub c_footer
+{
+ close(C);
+}
+
+sub h_footer
+{
+ print H "#endif\n";
+ close(H);
+}
diff --git a/util/szap/Makefile b/util/szap/Makefile
index 680793c..b341c74 100644
--- a/util/szap/Makefile
+++ b/util/szap/Makefile
@@ -1,35 +1,18 @@
-CC = gcc
-CFLAGS = -MD -Wall -g -O2 -I../../include -I../lib
-LFLAGS = -Wall -g -O2
-RM = rm -f
+# Makefile for linuxtv.org dvb-apps/util/szap
-TARGETS = szap tzap czap azap femon
-OBJS = szap.o tzap.o czap.o azap.o femon.o
+objects = lnb.o
-all: $(OBJS) $(TARGETS)
- @echo
- @echo "--------------------------------------------------------------------------------"
- @echo " please copy an appropriate channels.conf-XXX channel list for DVB-S/C/T"
- @echo
- @echo " to ~/.szap/channels.conf"
- @echo " ~/.czap/channels.conf"
- @echo " ~/.tzap/channels.conf"
- @echo
- @echo " and then call ./szap for DVB-S, ./czap for DVB-C or ./tzap for DVB-T"
- @echo "--------------------------------------------------------------------------------"
- @echo
+binaries = azap \
+ czap \
+ szap \
+ tzap
-szap: szap.o ../lib/lnb.o
- $(CC) $(LFLAGS) -o szap szap.o ../lib/lnb.o
+inst_bin = $(binaries)
-.c.o:
- $(CC) $(CFLAGS) -o $@ -c $<
+.PHONY: all
-.o:
- $(CC) $(LFLAGS) -o $@ $<
+all: $(binaries)
-clean:
- $(RM) $(TARGETS) core* *.o *.d .depend
-
--include $(wildcard *.d) dummy
+$(binaries): $(objects)
+include ../../Make.rules
diff --git a/util/szap/README b/util/szap/README
index 5c83c67..a990357 100644
--- a/util/szap/README
+++ b/util/szap/README
@@ -5,23 +5,29 @@ and demux API. They are also pretty useful to test your hardware.
For DVB-S, Astra Channel config file:
-$ ./szap -c channels.conf-dvbs-astra n24
+$ ./szap -c channels-conf/dvb-s/Astra-19.2E n24
will tune to N24. For DVB-C, Berlin Cable channel config:
-$ ./czap -c channels.conf-dvbc-berlin Arte
+$ ./czap -c channels-conf/dvb-c/de-Berlin Arte
For DVB-T, Berlin Config:
-$ ./czap -c channels.conf-dvbt-berlin phoenix
+$ ./tzap -c channels-conf/dvb-t/de-Berlin phoenix
-By default the MPEG stream is routed to a hardware decoder. If you want to
-record the stream to disk you will route it to the DVR device by using the
+For ATSC, Raleigh Durham Config:
+
+$ ./azap -c channels-conf/atsc/us-Raleigh-Durham WRAL
+
+will tune to WRAL's Digital Channel 5-1.
+
+By default the MPEG stream is routed to a hardware decoder. If you want to
+record the stream to disk you will route it to the DVR device by using the
'-r' option:
-$ ./czap -c channels.conf-dvbt-berlin phoenix -r
+$ ./tzap -c channels-conf/dvb-t/de-Berlin phoenix -r
[keep it running in one console]
-$ cat /dev/dvr/adapter0/dvr0 > /tmp/recording.ts
+$ cat /dev/dvb/adapter0/dvr0 > /tmp/recording.ts
[in a second console, will dump the MPEG transport stream to /tmp/recording.ts]
The status messages have the following meaning:
@@ -38,10 +44,9 @@ ber [0...0xffffffff] --- Bit Error Rate. The less the better.
unc [0...0xffffffff] --- Number of Uncorrectable Blocks.
Small numbers are Preferable.
-If everything is alright and all frontend circuits are working stable
+If everything is alright and all frontend circuits are working stable
(are locked) you should see a FE_HAS_LOCK in the rightmost line.
Good luck,
Holger
-
diff --git a/util/szap/azap.c b/util/szap/azap.c
index 14a1c6a..5bd7f33 100644
--- a/util/szap/azap.c
+++ b/util/szap/azap.c
@@ -103,7 +103,10 @@ int parse_int(int fd, int *val)
return -3; /* to fit in 32 bit */
};
+ errno = 0;
*val = strtol(number, NULL, 10);
+ if (errno == ERANGE)
+ return -4;
return 0;
}
@@ -189,9 +192,9 @@ int parse(const char *fname, const char *channel,
if ((err = try_parse_param(fd,
modulation_list, LIST_SIZE(modulation_list),
- (int *) &frontend->u.vsb.modulation,
- "modulation")))
+ &tmp, "modulation")))
return -4;
+ frontend->u.vsb.modulation = tmp;
if ((err = try_parse_int(fd, vpid, "Video PID")))
return -5;
@@ -389,4 +392,3 @@ int main(int argc, char **argv)
return 0;
}
-
diff --git a/util/szap/channels-conf/atsc/make_atsc_chanconf.pl b/util/szap/channels-conf/atsc/make_atsc_chanconf.pl
new file mode 100755
index 0000000..a5168e2
--- /dev/null
+++ b/util/szap/channels-conf/atsc/make_atsc_chanconf.pl
@@ -0,0 +1,110 @@
+#!/usr/bin/perl
+
+# Angel Li sent me this script to help in setting up a
+# ~/.azap/channels.conf file automagicly. This probbably
+# isn't the final version
+
+ use LWP;
+ use HTML::Form;
+ use HTTP::Cookies;
+ use XML::XPath;
+ use XML::XPath::XMLParser;
+
+ #$DEBUG = 1;
+
+ #
+ # Center frequencies for NTSC channels
+ #
+ @ntsc = (
+ 0, 0, 57, 63, 69, 79, 85, 177, 183, 189,
+ 195, 201, 207, 213, 473, 479, 485, 491, 497, 503,
+ 509, 515, 521, 527, 533, 539, 545, 551, 557, 563,
+ 569, 575, 581, 587, 593, 599, 605, 611, 617, 623,
+ 629, 635, 641, 647, 653, 659, 665, 671, 677, 683,
+ 689, 695, 701, 707, 713, 719, 725, 731, 737, 743,
+ 749, 755, 761, 767, 773, 779, 785, 791, 797, 803,
+ );
+
+ $ZIPCODE = 'txtZipcode';
+ $XML = 'stationXml';
+ $WEBSITE = 'http://www.antennaweb.org';
+
+ $zipCode = $ARGV[0];
+ unless ($zipCode) {
+ die "Zipcode missing on the command line";
+ }
+ unless ($zipCode =~ /^\d\d\d\d\d$/) {
+ die "Illegal zipcode: $zipCode";
+ }
+
+ $ua = LWP::UserAgent->new;
+ $ua->cookie_jar({});
+ push @{$ua->requests_redirectable}, 'POST';
+ $response = $ua->get($WEBSITE);
+ if ($response->is_success) {
+ $form = HTML::Form->parse($response);
+ $request = $form->click("btnStart");
+ $response2 = $ua->request($request);
+ if ($response2->is_success) {
+ $form2 = HTML::Form->parse($response2);
+ $form2->param($ZIPCODE, $zipCode);
+ $request2 = $form2->click("btnSubmit");
+ $response3 = $ua->request($request2);
+ $form3 = HTML::Form->parse($response3);
+ $request3 = $form3->click("btnContinue");
+ $response4 = $ua->request($request3);
+ if ($response4->is_success) {
+ $form4 = HTML::Form->parse($response4);
+ $xml = $form4->value($XML);
+ $xml =~ s/%22/"/g;
+ $xml =~ s/%2c/,/g;
+ $xml =~ s/%2f/\//g;
+ $xml =~ s/%3c/</g;
+ $xml =~ s/%3d/=/g;
+ $xml =~ s/%3e/>/g;
+ $xml =~ s/\+/ /g;
+ genConf($xml);
+ exit(0);
+ }
+ else {
+ print STDERR "Could not submit zipcode: $zipCode\n";
+ die $response3->status_line;
+ }
+ }
+ print STDERR "Could not reach zipcode page";
+ die $response2->status_line;
+ }
+ else {
+ print STDERR "Error reaching $WEBSITE\n";
+ die $response->status_line;
+ }
+
+ sub genConf {
+ my($xml) = @_;
+ my($s);
+ my($callSign);
+ my($channel);
+ my($c);
+ my($psipChannel);
+ my($freq);
+
+ $xp = XML::XPath->new(xml => $xml);
+ foreach $s ($xp->find('//Station[BroadcastType="D"]')->get_nodelist) {
+ if ($s->find('LiveStatus')->string_value eq "1") {
+ $callSign = $s->find('CallSign')->string_value;
+ $callSign =~ s/-DT//;
+ $channel = $s->find('Channel')->string_value; # Channel to tune
+ $psipChannel = $s->find('PsipChannel')->string_value;
+
+ if ($DEBUG) {
+ print STDERR $callSign, "\t", $channel, " -> ", $psipChannel, "\n";
+ }
+
+ $psipChannel =~ s/\.\d+$//;
+ $freq = $ntsc[$channel]*1000000;
+ if ($freq) {
+ print $callSign, ":", $freq, ":8VSB:0:0\n";
+ }
+ }
+ }
+ }
diff --git a/util/szap/channels-conf/atsc/us-Raleigh-Durham b/util/szap/channels-conf/atsc/us-Raleigh-Durham
new file mode 100644
index 0000000..48d14d2
--- /dev/null
+++ b/util/szap/channels-conf/atsc/us-Raleigh-Durham
@@ -0,0 +1,8 @@
+# Most of the major channels in the Raleigh Durham Area. Frequencies the NTSC center freq.
+WRAL:707000000:8VSB:33:36
+WNCN:719000000:8VSB:49:52
+WTVD:701000000:8VSB:49:52
+WRAZ:683000000:8VSB:49:52
+WUNC:743000000:8VSB:49:52
+WRDU:551000000:8VSB:33:36
+WLFL:731000000:8VSB:33:36
diff --git a/util/szap/channels.conf-dvbc-berlin b/util/szap/channels-conf/dvb-c/de-Berlin
index 7fb05a5..0f2cafd 100644
--- a/util/szap/channels.conf-dvbc-berlin
+++ b/util/szap/channels-conf/dvb-c/de-Berlin
@@ -1,7 +1,7 @@
3sat:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:210:220
ARD-Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1805
CNBC:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:510:520
-DLF-Köln:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:810
+DLF-Köln:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:810
DLR-Berlin:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:710
EinsExtra:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102
EinsFestival:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202
@@ -20,8 +20,8 @@ RADIOmultikulti:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1301
Radio 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:701
SFB1:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602
SWR2:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1401
-SÜDWEST BW:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:801:802
-SÜDWEST RP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3101:3102
+SÃœDWEST BW:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:801:802
+SÃœDWEST RP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3101:3102
WDR 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1501
WDR 5:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1601
ZDF:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:110:120
@@ -31,7 +31,7 @@ ZDFinfokanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:610:620
ZDFtheaterkanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
JUMP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1001
SPUTNIK:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1201
-Österreich 1:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:169
+Österreich 1:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:169
ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632
ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632
Adagio:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
@@ -153,7 +153,7 @@ HEIMATKANAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
HIP HOP/R&B:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:576
JUNIOR:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256
K-TOON:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
-KLASSIK POPULÄR:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:624
+KLASSIK POPULÄR:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:624
KRIMI &CO:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
LOVE SONGS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592
NEW COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384
diff --git a/util/szap/channels-conf/dvb-s/Astra-19.2E b/util/szap/channels-conf/dvb-s/Astra-19.2E
new file mode 100644
index 0000000..6e634b9
--- /dev/null
+++ b/util/szap/channels-conf/dvb-s/Astra-19.2E
@@ -0,0 +1,226 @@
+Das Erste:11837:h:0:27500:101:102:28106
+ZDF:11954:h:0:27500:110:120:28006
+3sat:11954:h:0:27500:210:220:28007
+EinsMuXx:12110:h:0:27500:301:302:28203
+EinsFestival:12110:h:0:27500:201:202:28202
+EinsExtra:12110:h:0:27500:101:102:28201
+MDR FERNSEHEN:12110:h:0:27500:401:402:28204
+ORB-Fernsehen:12110:h:0:27500:501:502:28205
+B1 Berlin:12110:h:0:27500:601:602:28206
+SWR Fernsehen:11837:h:0:27500:801:802:28113
+SR Fernsehen Suedwes:11837:h:0:27500:501:502:28110
+hessen fernsehen:11837:h:0:27500:301:302:28108
+WDR FERNSEHEN:11837:h:0:27500:601:602:28111
+Bayerisches FS:11837:h:0:27500:201:202:28107
+N3:12110:h:0:27500:2401:2402:28224
+BR-alpha:11837:h:0:27500:701:702:28112
+KiKa:11954:h:0:27500:310:320:28008
+arte:11836:h:0:27500:401:402:28109
+ZDF Theaterkanal:11954:h:0:27500:1110:1120:28016
+ZDF.info:11954:h:0:27500:610:620:28011
+ZDF.doku:11954:h:0:27500:660:670:28014
+Phoenix:11837:h:0:27500:901:902:28114
+DW-tv:10786:v:0:21997:305:306:9005
+RTL Television:12188:h:0:27500:163:104:12003
+SAT.1:12480:v:0:27500:1791:1792:46
+ProSieben:12480:v:0:27500:255:256:898
+RTL2:12188:h:0:27500:166:128:12020
+Super RTL:12188:h:0:27500:165:120:12040
+KABEL1:12480:v:0:27500:511:512:899
+VOX:12188:h:0:27500:167:136:12060
+tm3:12480:v:0:27500:767:768:897
+Bloomberg TV Germany:12552:v:0:22000:162:99:12160
+EuroNews:11954:h:0:27500:2221:2233:28015
+N24:12480:v:0:27500:2047:2048:47
+n-tv:12670:v:0:22000:162:96:12730
+DSF:12480:v:0:27500:1023:1024:900
+Eurosport:11954:h:0:27500:410:420:28009
+Via 1 - Sch ner Re:12148:h:0:27500:511:512:44
+Home Order Tel:12480:v:0:27500:1279:1280:40
+QVC GERMANY:12552:v:0:22000:165:166:12100
+TW 1:12692:h:0:22000:166:167:13013
+Canal Canarias:12441:v:0:27500:513:681:29700
+ProSieben A:12051:v:0:27500:161:84:20002
+ProSieben CH:12051:v:0:27500:289:290:20001
+Kabel 1 Austria:12051:v:0:27500:166:167:20004
+Kabel 1 Schweiz:12051:v:0:27500:162:163:20003
+CNN Int.:12168:v:0:27500:165:100:28512
+Sky News:12552:v:0:22000:305:306:3995
+Travel:12168:v:0:27500:163:92:28001
+AB SAT / XXL:12266:h:0:27500:164:96:17004
+MOTEURS:12266:h:0:27500:160:80:17000
+HOT GM:12148:h:0:27500:767:768:45
+KTO:12129:v:0:27500:170:120:8411
+LA CINQUIEME:12207:v:0:27500:160:80:8501
+LCP:12207:v:0:27500:165:100:8506
+LibertyTV.com:12611:v:0:22000:941:942:12280
+TV5 Europe:12611:v:0:22000:45:46:12240
+Motors TV:12611:v:0:22000:191:194:12300
+Wishline:12611:v:0:22000:214:216:12320
+TV 5:10786:v:0:21997:164:112:9001
+RTM - MAROC:10786:v:0:21997:162:96:9002
+ESC1 - EGYPTE:10786:v:0:21997:163:104:9003
+RAI 1:10786:v:0:21997:289:290:9004
+RTPI:10786:v:0:21997:300:301:9006
+TV7:10786:v:0:21997:166:128:9007
+ARTE:10786:v:0:21997:167:136:9009
+Colourbars:12611:v:0:22000:48:49:3982
+Alice:12611:v:0:22000:162:96:12200
+Video Italia:12611:v:0:22000:121:122:12220
+ANDALUCIA TV:11934:v:0:27500:166:104:29011
+TVC INT.:12441:v:0:27500:512:660:29701
+TV4:11992:h:0:27500:165:98:20365
+TV Niepokalanow:11876:h:0:27500:161:82:20601
+VIVA:12670:v:0:22000:309:310:12732
+VIVA ZWEI:12552:v:0:22000:171:172:12120
+MTV Central:12699:v:0:22000:3031:3032:28643
+ONYX:12692:h:1:27500:161:84:502
+VIVA polska:11603:h:1:27500:190:191:611
+DeeJay TV:11603:h:1:27500:160:161:602
+NBC:11053:h:1:27500:550:551:8008
+EWTN:10722:h:1:29900:1001:1201:4601
+MTA INTL:10722:h:1:29900:1004:1204:4604
+VOX:11053:h:1:27500:500:501:8002
+SAT.1 A:11053:h:1:27500:511:512:8003
+RTL2 AUSTRIA:11053:h:1:27500:520:521:8004
+ZDF:11053:h:1:27500:570:571:8011
+K-TV:11053:h:1:27500:580:581:8012
+RTL Television:11053:h:1:27500:160:80:8001
+ARTE:11059:v:1:6510:98:99:1
+HOT Italia:11095:h:1:27500:4194:4195:3714
+Olisat:11095:h:1:27500:33:34:3718
+VIVA-POLSKA:11128:h:1:4340:98:99:1
+DW-tv:11195:v:1:9099:101:102:5301
+Canal 24 Horas:11203:h:1:3999:4130:4131:5301
+TV5:11337:v:1:5631:512:640:1
+SAT.1 CH:11603:h:1:27500:101:102:601
+KurdSat:11603:h:1:27500:111:112:603
+ARD "Das Erste":11603:h:1:27500:172:173:606
+RTL 2 CH:11603:h:1:27500:175:176:609
+Super RTL A:11603:h:1:27500:180:181:610
+TV ROMANIA:11622:v:1:27500:227:247:10707
+MRTV:11622:v:1:27500:222:242:10702
+102.5 HIT Ch:11622:v:1:27500:224:244:10704
+TLC SAT:11622:v:1:27500:225:245:10705
+PRO-SAT:11622:v:1:27500:246:226:10706
+Channel SUN:11622:v:1:27500:229:249:10709
+Racing Channel:11622:v:1:27500:228:248:10708
+3 ABN:11622:v:1:27500:221:241:10701
+Bloom.Germany:11642:h:1:27500:1460:1420:4
+Bloomberg TV UK:11642:h:1:27500:1560:1520:4
+Sat 7:11642:h:1:27500:1660:1620:4
+EDTV 1:11746:h:1:27500:4130:4131:9501
+EDTV SPORT:11746:h:1:27500:4386:4387:9502
+EDTV BUSINESS:11746:h:1:27500:4642:4643:9503
+EDTV DRAMA:11746:h:1:27500:4898:4899:9504
+RAI1:11765:v:1:27499:160:80:3401
+RAI2:11765:v:1:27499:161:84:3402
+RAI3:11765:v:1:27499:162:88:3403
+RaiWayTEST2:11765:v:1:27499:516:654:3405
+RAIMOSAICO:11765:v:1:27499:518:8191:3407
+RAINews24:11803:v:1:27500:516:654:3301
+CAMERA DEPUTATI:11803:v:1:27500:517:655:3302
+TELEPACE:11803:v:1:27500:515:653:3304
+RAISPORTSAT:11803:v:1:27500:512:650:3305
+RAINettunoSAT2:11803:v:1:27500:513:651:3306
+RAIeducational:11803:v:1:27500:514:652:3307
+RAINettunoSAT1:11803:v:1:27500:519:657:3308
+SAT2000:11803:v:1:27500:518:656:3309
+I1:11918:v:1:27499:512:650:1
+C5:11918:v:1:27499:513:660:2
+R4:11918:v:1:27499:514:670:3
+Telesierra:12091:h:1:27500:4160:4161:8704
+C. Milagro:12091:h:1:27500:4368:4369:8711
+Italia Sat:12091:h:1:27500:4600:4601:8728
+TVE Internacional:12091:h:1:27500:4208:4209:8707
+Fiesta:12091:h:1:27500:4432:4433:8720
+Retelsat:12091:h:1:27500:4464:4465:8722
+ART EUROPE:12013:h:1:27495:164:96:450
+EGYPT SAT. CH. 2:12013:h:1:27495:166:104:470
+IQRA:12013:h:1:27495:168:112:474
+MAURITANIA TV:12110:v:1:27500:230:231:704
+ARMENIA TV:12110:v:1:27500:240:241:705
+SAILING CHANNEL:12110:v:1:27500:260:261:707
+AL JAZEERA:12110:v:1:27500:270:271:708
+Coming Soon TV:12110:v:1:27500:310:311:717
+SaluteBenessere:12110:v:1:27500:320:321:718
+AH-EDP1:12148:v:1:27499:96:97:7201
+AH-EDP2:12148:v:1:27499:112:113:7202
+Espresso:12148:v:1:27499:192:193:7203
+Alice:12148:v:1:27499:160:161:7220
+Nuvolari:12148:v:1:27499:176:177:7221
+Leonardo:12148:v:1:27499:128:129:7222
+AH-EDP3:12148:v:1:27499:36:37:7205
+OTE Promo:12187:v:1:27500:517:655:1001
+RTS SAT:12187:v:1:27500:519:657:1022
+ERT SAT:12187:v:1:27500:514:652:1102
+EXTRA:12187:v:1:27500:516:654:1106
+TRIAL:12187:v:1:27500:513:651:1108
+Minimax:11303:h:1:19540:300:301:3
+TVN1:12209:h:1:5631:4194:4195:1
+RR TEST:10978:v:1:8998:33:34:1
+TV 5 Thailand:10978:v:1:8998:1057:1058:2
+TEST-1:10978:v:1:8998:3105:3106:4
+FASHION:12244:h:1:27500:123:133:103
+AJARA TV:12244:h:1:27500:127:137:107
+SLO-TV1:12300:v:1:27495:200:201:3201
+POLONIA 1:12302:v:1:27500:205:206:3203
+SUPER 1:12302:v:1:27500:207:208:3207
+NAPOLI INT.:12302:v:1:27500:240:241:3210
+MAGIC:12302:v:1:27500:245:246:3211
+COUNTDOWN:12302:v:1:27500:235:236:3212
+TBNE:12302:v:1:27500:230:231:3213
+NAPOLI CHANNEL:12302:v:1:27500:227:228:3215
+KURDISTAN TV:12302:v:1:27500:225:226:3214
+ATLAS TV:12379:v:1:27500:3022:3032:3002
+TELE 24 SWITZERLAND:12379:v:1:27500:3023:3033:3003
+Abu Dhabi TV:12379:v:1:27500:3024:3034:3004
+RTV MONTENEGRO:12379:v:1:27500:3026:3036:3006
+JAAM-E-JAM 1:12436:h:1:27500:160:80:1
+JAAM-E-JAM 2:12436:h:1:27500:161:82:2
+SAHAR:12436:h:1:27500:162:84:3
+SAHAR 2:12436:h:1:27500:163:86:4
+IRINN:12436:h:1:27500:164:88:5
+Musicmax:11303:h:1:19540:500:501:6
+TEST:12474:h:1:27500:771:8191:10608
+EbS:12474:h:1:27500:101:201:10601
+MOU.2:12474:h:1:27500:42:43:10602
+PINK PLUS:12474:h:1:27500:308:256:10605
+LibertyTV.com:12474:h:1:27500:941:942:10603
+2M Maroc:12474:h:1:27500:601:602:10607
+ZEE TV:12474:h:1:27500:910:911:10604
+WorldNet Europe:12483:v:1:8299:4260:4220:1
+WorldNet:12483:v:1:8299:4560:4520:4
+SICILIA INTERNATIONA:12519:v:1:27499:501:502:8309
+SARDEGNA UNO:12519:v:1:27499:503:504:8310
+EuroMed:12519:v:1:27499:510:511:8312
+TGRT:12519:v:1:27499:505:506:8313
+VIDEOLINA:12519:v:1:27499:515:516:8318
+MEDIOLANUM:12538:h:1:27500:1131:1132:8987
+www.travel:12538:h:1:27500:1180:1183:8992
+MonteCarloSat:12538:h:1:27500:5126:5122:8877
+Bulgaria TV:12538:h:1:27500:4612:4613:8827
+TVN1:12571:h:1:5631:4194:4195:1
+JSTV 1:12595:v:1:27500:2000:2001:8213
+JSTV 2:12595:v:1:27500:2011:2013:8214
+MBC:12595:v:1:27500:160:80:8201
+ANN:12595:v:1:27500:161:84:8202
+BET:12595:v:1:27500:167:108:8208
+EuroNews:12595:v:1:27500:2221:2231:8211
+Sharjah Arabs:12653:h:1:27500:1160:1120:1
+Qatar Arabs:12653:h:1:27500:1260:1220:2
+Saudi 1 Arabs:12653:h:1:27500:1360:1320:3
+Kuwait Arabs:12653:h:1:27500:1460:1420:4
+Libya Arabs:12653:h:1:27500:1560:1520:5
+Sudan Arabs:12653:h:1:27500:1660:1620:6
+Oman Arabs:12653:h:1:27500:1760:1720:7
+Jordan Arabs:12653:h:1:27500:1860:1820:8
+IRAQ TV:12653:h:1:27500:1960:1920:9
+Dubai Sport:12653:h:1:27500:1060:1020:10
+Digitaly:12672:v:1:27500:220:221:4203
+Telemarket:12672:v:1:27500:350:351:4211
+eVision:12672:v:1:27500:360:361:4214
+Thai TV5:12672:v:1:27500:200:201:4201
+Studio Europa:12672:v:1:27500:230:231:4204
+Video Italia:12672:v:1:27500:340:341:4210
+GAME NETWORK:12672:v:1:27500:291:292:4213
diff --git a/util/szap/channels-conf/dvb-s/Astra-28.2E b/util/szap/channels-conf/dvb-s/Astra-28.2E
new file mode 100644
index 0000000..cbba30a
--- /dev/null
+++ b/util/szap/channels-conf/dvb-s/Astra-28.2E
@@ -0,0 +1,522 @@
+BBC 1 London:10773:h:0:22000:2304:2306:6301
+BBC 2 England:10773:h:0:22000:2320:2322:6302
+BBC NEWS 24:10773:h:0:22000:2329:2331:6304
+ETV:10773:h:0:22000:2333:2335:6306
+BBC TES 3:10773:h:0:22000:2325:2327:6315
+CBBC Channel:10773:h:0:22000:2325:2327:6317
+CBeebies:10773:h:0:22000:2333:2335:6318
+BBC 1 NI:10773:h:0:22000:2316:2318:6331
+BBC R Cymru:10773:h:0:22000:0:2340:6363
+BBC TES Test:10773:h:0:22000:0:0:6308
+BBC TES 2:10773:h:0:22000:0:0:6309
+BBC FOUR:10773:h:0:22000:0:0:6316
+BBC THREE:10773:h:0:22000:0:0:6319
+[1341]:11469:h:0:27500:521:649:4929
+[1342]:11469:h:0:27500:522:650:4930
+MMS 5:11469:h:0:27500:0:0:5044
+MMS 6:11469:h:0:27500:0:0:5045
+Sky Active:11469:h:0:27500:0:0:5107
+[140a]:11469:h:0:27500:518:646:5130
+[146b]:11469:h:0:27500:512:640:5227
+[146c]:11469:h:0:27500:513:641:5228
+[1016]:11469:h:0:27500:514:642:4118
+[10e9]:11469:h:0:27500:519:647:4329
+[1279]:11469:h:0:27500:520:648:4729
+Sky Customer Service:11469:h:0:27500:0:0:5240
+Directgov - Govt Info:11469:h:0:27500:0:0:5241
+[1596]:11469:h:0:27500:515:643:5526
+[1597]:11469:h:0:27500:516:644:5527
+[159a]:11469:h:0:27500:517:645:5530
+[15a4]:11469:h:0:27500:0:0:5540
+[05dc]:11469:h:0:27500:0:0:1500
+[1017]:11469:h:0:27500:0:0:4119
+Sky Box Office:11469:h:0:27500:0:0:4121
+Sky Box Office:11469:h:0:27500:0:0:4122
+Sky Box Office:11469:h:0:27500:0:0:4123
+Sky Box Office:11469:h:0:27500:0:0:4124
+Sky Box Office:11469:h:0:27500:0:0:4129
+POP:12285:v:0:27500:2311:2312:52500
+3751 PH:12285:v:0:27500:2311:2312:52501
+Chart Show TV:12285:v:0:27500:2309:2310:52505
+3761 PH:12285:v:0:27500:2313:2314:52512
+The Vault:12285:v:0:27500:2322:2323:52515
+Chase-it.tv:12285:v:0:27500:2318:2319:52520
+OBE:12285:v:0:27500:2307:2308:52525
+Tiny Pop:12285:v:0:27500:2316:2317:52530
+Spice Extreme:12285:v:0:27500:2320:2321:52561
+Climax3 - 1:12285:v:0:27500:2324:2325:52562
+Climax3 - 2:12285:v:0:27500:2326:2327:52563
+Climax3 - 3:12285:v:0:27500:2328:2329:52564
+Adult Channel:12285:v:0:27500:2330:2331:52565
+Playboy TV:12285:v:0:27500:2313:2314:52566
+52567:12285:v:0:27500:2330:2331:52567
+3911 PH:12285:v:0:27500:2320:2321:52581
+IDMT:12148:h:0:27500:2307:2308:52200
+ Broadband UK:12148:h:0:27500:2305:2306:52210
+52220:12148:h:0:27500:2309:2310:52220
+Trouble Reload:12148:h:0:27500:2311:2312:52230
+Challenge+1:12148:h:0:27500:2314:2315:52232
+Ftn:12148:h:0:27500:0:0:52231
+[15ff]:10920:h:0:22000:516:644:5631
+D'covery H&L+:10920:h:0:22000:2305:2306:50003
+Eurosportnews:10920:h:0:22000:2307:2308:5009
+Hallmark:10920:h:0:22000:2310:2311:5010
+[13a2]:10920:h:0:22000:512:640:5026
+[13a4]:10920:h:0:22000:514:642:5028
+[13a5]:10920:h:0:22000:515:643:5029
+[05e6]:10920:h:0:22000:0:0:1510
+Sky Box Office:10920:h:0:22000:0:0:4122
+Sky Box Office:10920:h:0:22000:0:0:4123
+Sky Box Office:10920:h:0:22000:0:0:4124
+Sky Box Office:10920:h:0:22000:0:0:4129
+SportxxxBabes:10920:h:0:22000:0:0:4137
+[1393]:10920:h:0:22000:0:0:5011
+[15fb]:10920:h:0:22000:0:0:5627
+SAB TV:12226:h:0:27500:2310:2311:52401
+Performance:12226:h:0:27500:2312:2313:52402
+channel U:12226:h:0:27500:2314:2315:52403
+Gems.tv:12226:h:0:27500:2317:2318:52404
+Soundtrack ch.:12226:h:0:27500:2307:2308:52405
+HorrorChannel:12226:h:0:27500:2342:2343:52406
+Chat Box:12226:h:0:27500:2319:2320:52407
+Golf Channel:12226:h:0:27500:2321:2322:52408
+Ex&Mart TV:12226:h:0:27500:2323:2324:52409
+TVW Select:12226:h:0:27500:2305:2306:52412
+Game In TV:12226:h:0:27500:2335:2336:52414
+Majestic TV:12226:h:0:27500:2340:2341:52415
+18PlusXXX:12226:h:0:27500:0:0:52410
+XXXHousewive:12226:h:0:27500:0:0:52411
+52421:12226:h:0:27500:0:0:52421
+[10ea]:11603:v:0:27500:514:662:4330
+[114e]:11603:v:0:27500:515:663:4430
+[11b2]:11603:v:0:27500:516:664:4530
+[1215]:11603:v:0:27500:521:669:4629
+[1216]:11603:v:0:27500:517:665:4630
+[127a]:11603:v:0:27500:518:666:4730
+[12de]:11603:v:0:27500:519:667:4830
+[13a6]:11603:v:0:27500:512:660:5030
+[1409]:11603:v:0:27500:522:670:5129
+[146a]:11603:v:0:27500:520:668:5226
+[1599]:11603:v:0:27500:523:671:5529
+[15fa]:11603:v:0:27500:513:661:5626
+Sky Box Office:11603:v:0:27500:0:0:4124
+Sky Box Office:11603:v:0:27500:0:0:4129
+MMS 4:11603:v:0:27500:0:0:5043
+MMS 8:11603:v:0:27500:0:0:5047
+[1603]:11603:v:0:27500:0:0:5635
+[05e9]:11603:v:0:27500:0:0:1513
+Sky Box Office:11603:v:0:27500:0:0:4121
+Sky Box Office:11603:v:0:27500:0:0:4122
+Sky Box Office:11603:v:0:27500:0:0:4123
+1391:10935:v:0:22000:2321:2320:5421
+1392:10935:v:0:22000:2305:2320:5422
+1393:10935:v:0:22000:2306:2320:5423
+1394:10935:v:0:22000:2307:2320:5424
+1395:10935:v:0:22000:2308:2320:5425
+1396:10935:v:0:22000:2309:2320:5426
+1397:10935:v:0:22000:2310:2320:5427
+1398:10935:v:0:22000:2311:2320:5428
+1399:10935:v:0:22000:2312:2320:5429
+1471:10935:v:0:22000:2305:2313:5471
+1472:10935:v:0:22000:2306:2314:5472
+1473:10935:v:0:22000:2307:2315:5473
+1474:10935:v:0:22000:2308:2316:5474
+1475:10935:v:0:22000:2309:2317:5475
+1476:10935:v:0:22000:2310:2318:5476
+1477:10935:v:0:22000:2311:2319:5477
+1478:10935:v:0:22000:2312:2320:5478
+[05ea]:10935:v:0:22000:0:0:1514
+1326:10935:v:0:22000:0:0:5307
+1334:10935:v:0:22000:0:0:5310
+SPl:10935:v:0:22000:0:0:5404
+rc:10935:v:0:22000:0:0:5407
+nata:10935:v:0:22000:0:0:5466
+natd:10935:v:0:22000:0:0:5467
+ISM Sky News v6:11507:h:0:27500:2305:2306:9318
+ISM Movies v6:11507:h:0:27500:0:0:9319
+EIA2 Test:11507:h:0:27500:2305:2306:9322
+UK Online test:11507:h:0:27500:0:0:9323
+1784:11507:h:0:27500:2305:2306:9324
+1786:11507:h:0:27500:0:0:9325
+SCS:11507:h:0:27500:0:0:9326
+STT:11507:h:0:27500:2305:2306:9327
+1787:11507:h:0:27500:2305:2306:9329
+5ADT:11507:h:0:27500:2305:2306:9331
+EIA2 Test 6:11507:h:0:27500:2305:2306:9332
+8N2:11507:h:0:27500:0:0:9335
+EIA2 Test 5:11507:h:0:27500:2305:2306:9336
+[2479]:11507:h:0:27500:0:0:9337
+[247a]:11507:h:0:27500:0:0:9338
+7909:11507:h:0:27500:2305:2306:3909
+EIA2 Test 3:11507:h:0:27500:2305:2306:4909
+EIA2 Test 4:11507:h:0:27500:2305:2306:4912
+ISM Test1 v5:11507:h:0:27500:2305:2306:5902
+PlayJam:11507:h:0:27500:0:2445:9306
+PlayMonteCarlo & Roulette:11507:h:0:27500:0:2457:9308
+PlayJam test:11507:h:0:27500:0:2445:9310
+ISM Sky One v6:11507:h:0:27500:2305:2306:9316
+ISM Sports 1 v6:11507:h:0:27500:2305:2306:9317
+[05f3]:11507:h:0:27500:0:0:1523
+Playboy / Adult:11507:h:0:27500:0:0:4128
+Playboy TV:11507:h:0:27500:0:0:4131
+Private Girls:11507:h:0:27500:0:0:4133
+XXX TV:11507:h:0:27500:0:0:4134
+Amateur Babes:11507:h:0:27500:0:0:4135
+[1207]:11507:h:0:27500:0:0:4615
+[1209]:11507:h:0:27500:0:0:4617
+[232d]:11507:h:0:27500:0:0:9005
+YO-YO" test:11507:h:0:27500:0:0:9309
+UCB TV:12070:h:0:27500:2313:2314:52001
+ATN:12070:h:0:27500:2310:2311:52002
+Overload:12070:h:0:27500:2306:2307:52003
+Golf Pro-Shop:12070:h:0:27500:2315:2316:52004
+You TV:12070:h:0:27500:2336:2337:52005
+Escape:12070:h:0:27500:2317:2318:52006
+52007:12070:h:0:27500:2324:2325:52007
+Get Lucky TV:12070:h:0:27500:2319:2320:52008
+[fffe]:12070:h:0:27500:0:0:65534
+Wonderful:12070:h:0:27500:2308:2309:52009
+Musicians Chnl:12070:h:0:27500:2326:2327:52010
+Rangers TV:12070:h:0:27500:2328:2329:52011
+Celtic TV:12070:h:0:27500:2330:2331:52012
+Advert Channel:12070:h:0:27500:2332:2333:52013
+LONDON TV:12070:h:0:27500:2334:2335:52014
+Pure Dance:12070:h:0:27500:0:2312:52025
+Club Asia:12070:h:0:27500:0:2305:52026
+Setanta Sports:12070:h:0:27500:0:0:52021
+Setanta Sports:12070:h:0:27500:0:0:52022
+Setanta PPV2:12070:h:0:27500:0:0:52032
+FilmFour:11565:v:0:27500:2320:2321:50500
+FilmFour +1:11565:v:0:27500:2323:2324:50505
+Film4 Weekly:11565:v:0:27500:2326:2327:50510
+E4:11565:v:0:27500:2329:2330:50515
+Game 6:11565:v:0:27500:0:2336:50540
+Game 7:11565:v:0:27500:0:2342:50541
+Game 8:11565:v:0:27500:0:2344:50542
+FF TEST1:11565:v:0:27500:2320:2321:50543
+PCNE Chinese:11565:v:0:27500:6144:6145:50550
+Bloomberg:11565:v:0:27500:2316:2317:50555
+[05f5]:11565:v:0:27500:0:0:1525
+SCRD4:10861:h:0:22000:0:0:8009
+SBZP:10861:h:0:22000:0:0:8059
+LMIN:10861:h:0:22000:0:0:8108
+TRLN:10861:h:0:22000:0:0:8116
+SCD2:10861:h:0:22000:0:0:8126
+DOMI:10861:h:0:22000:0:0:8145
+WINC:10861:h:0:22000:2325:2326:8164
+The Betting Zone:10861:h:0:22000:0:0:8186
+TLM(Browser):10861:h:0:22000:2342:2344:8888
+Disney Chnl:10861:h:0:22000:2308:2309:9001
+Disney Chnl +1:10861:h:0:22000:2313:2314:9002
+Toon Disney:10861:h:0:22000:2317:2318:9003
+Playhse Disney:10861:h:0:22000:2320:2321:9004
+The Betting Zone:10861:h:0:22000:2336:2338:50008
+[05f6]:10861:h:0:22000:0:0:1526
+ALTU:10861:h:0:22000:0:0:8087
+DCT2 (t51):10861:h:0:22000:0:0:8999
+DCT (t51):10861:h:0:22000:0:0:9000
+Sky Travel +1:10876:v:0:22000:2310:2318:3905
+Sky Travel Active Dummy:10876:v:0:22000:0:0:4911
+Sky Travel:10876:v:0:22000:2308:2309:5005
+5006:10876:v:0:22000:2308:2309:5006
+Sky Trvl Extra:10876:v:0:22000:2305:2306:9312
+[0602]:10876:v:0:22000:0:0:1538
+Tel Sell:12460:h:0:27500:2319:2320:50832
+mSync:12460:h:0:27500:0:0:50837
+NASN:12460:h:0:27500:2322:2323:50839
+Classics TV:12460:h:0:27500:2324:2325:50840
+Information TV:12460:h:0:27500:2326:2327:50841
+Wrestling Chnl:12460:h:0:27500:2329:2330:50842
+TWC Reloaded:12460:h:0:27500:2331:2332:50843
+FRIENDLY TV:12460:h:0:27500:2333:2334:50848
+McColls:12460:h:0:27500:0:2335:50851
+Moto:12460:h:0:27500:0:2336:50852
+Teds FM:12460:h:0:27500:0:2337:50853
+Topps FM:12460:h:0:27500:0:2338:50855
+Kiss:12460:h:0:27500:0:2339:50856
+Smash Hits!:12460:h:0:27500:0:2340:50857
+Kerrang:12460:h:0:27500:0:2341:50858
+The Hits:12460:h:0:27500:0:2342:50859
+Magic:12460:h:0:27500:0:2343:50860
+Q:12460:h:0:27500:0:2344:50861
+MOJO:12460:h:0:27500:0:2345:50862
+Heat:12460:h:0:27500:0:2346:50863
+GlobeCast:12460:h:0:27500:0:2347:50864
+PTV Prime:12460:h:0:27500:2315:2316:50865
+Fashion TV:12460:h:0:27500:0:0:50850
+Best Direct:12246:v:0:27500:2314:2315:53500
+BestDirect+:12246:v:0:27500:2316:2317:53505
+Dating Channel:12246:v:0:27500:2320:2321:53515
+Wine TV:12246:v:0:27500:2323:2324:53520
+Flaunt:12246:v:0:27500:2326:2327:53525
+Scuzz:12246:v:0:27500:2328:2329:53530
+The Amp:12246:v:0:27500:2330:2331:53535
+Radio Caroline:12246:v:0:27500:0:2332:53550
+Amrit Bani:12246:v:0:27500:0:2333:53551
+Desi Radio:12246:v:0:27500:0:2334:53552
+CalvaryRadio:12246:v:0:27500:0:2335:53553
+Apple FM:12246:v:0:27500:0:2336:53554
+TWR:12246:v:0:27500:0:2337:53555
+Spectrum 1:12246:v:0:27500:0:2338:53556
+RTE Europe:12246:v:0:27500:0:2339:53557
+WRN Europe:12246:v:0:27500:0:2340:53558
+Raaj Radio:12246:v:0:27500:0:2341:53559
+On Air:12246:v:0:27500:0:2342:53560
+53561:12246:v:0:27500:0:2306:53561
+PulseUnsignd:12246:v:0:27500:0:2343:53564
+53581:12246:v:0:27500:0:0:53581
+RTE One:10743:h:0:22000:2306:2307:9601
+RTE TWO:10743:h:0:22000:2309:2310:9602
+TG4:10743:h:0:22000:2312:2313:9603
+TV3:10743:h:0:22000:2315:2316:9605
+DW-TV:10743:h:0:22000:2318:2319:9606
+TVEi:10743:h:0:22000:2320:2321:9607
+RTE Radio 1:10743:h:0:22000:0:2322:9611
+RTE 2FM:10743:h:0:22000:0:2323:9612
+RTE R na G:10743:h:0:22000:0:2324:9613
+RTE Lyric fm:10743:h:0:22000:0:2325:9614
+BBC R5 Live:10802:h:0:22000:0:2338:6401
+ETV2:10802:h:0:22000:2304:2306:6407
+BBC 1 Wales:10802:h:0:22000:2304:2306:6411
+BBC 2W:10802:h:0:22000:2321:2323:6412
+BBC 1 Scotland:10802:h:0:22000:2311:2313:6421
+BBC 2 Scotland:10802:h:0:22000:2325:2327:6422
+BBC 2 NI:10802:h:0:22000:2329:2331:6432
+BBC R1:10802:h:0:22000:0:2333:6451
+BBC R2:10802:h:0:22000:0:2334:6452
+BBC R3:10802:h:0:22000:0:2335:6453
+BBC R4 FM:10802:h:0:22000:0:2336:6454
+BBC R4 LW:10802:h:0:22000:0:2337:6455
+BBC R Scot.:10802:h:0:22000:0:2339:6457
+BBC R Wales:10802:h:0:22000:0:2340:6458
+BBC R Ulster:10802:h:0:22000:0:2341:6459
+BBC Asian Nt.:10802:h:0:22000:0:2342:6460
+BBC World Sv.:10802:h:0:22000:0:2343:6461
+ETV3:10802:h:0:22000:0:2333:6462
+BBC 5L SportX:10802:h:0:22000:0:2344:6464
+BBC WS Extra:10802:h:0:22000:0:2345:6465
+1Xtra BBC:10802:h:0:22000:0:2347:6466
+BBC 6 Music:10802:h:0:22000:0:2346:6467
+BBC 7:10802:h:0:22000:0:2348:6468
+BBC R n Gael:10802:h:0:22000:0:2349:6469
+T4 STRM-0:10847:v:0:22000:2305:2306:6900
+T4 STRM-1:10847:v:0:22000:2320:2321:6901
+BBC PARL'MNT:10847:v:0:22000:2327:2328:6902
+BBC 1 East (W):10847:v:0:22000:2338:2339:6903
+BBC 1 CI:10847:v:0:22000:2343:2344:6904
+T4 DEV-0:10847:v:0:22000:2305:2306:6990
+T4 DEV-1:10847:v:0:22000:2320:2321:6991
+T4 DEV-2:10847:v:0:22000:2327:2328:6992
+T4 DEV-3:10847:v:0:22000:2338:2339:6993
+T4 DEV-4:10847:v:0:22000:2343:2344:6994
+BBC 1 W Mids:10788:v:0:22000:2305:2306:10301
+BBC 1 N West:10788:v:0:22000:2318:2319:10302
+BBC 1 Yrks&Lin:10788:v:0:22000:2321:2322:10303
+BBC 1 Yorks:10788:v:0:22000:2324:2325:10304
+BBC 1 E Mids:10788:v:0:22000:2327:2328:10305
+BBC 1 East (E):10788:v:0:22000:2330:2331:10306
+ETV5:10788:v:0:22000:2305:2306:10321
+BBC 1 West:10817:v:0:22000:2305:2306:10351
+BBC 1 S East:10817:v:0:22000:2317:2318:10352
+BBC 1 South:10817:v:0:22000:2320:2321:10353
+BBC 1 S West:10817:v:0:22000:2323:2324:10354
+BBC 1 NE & C:10817:v:0:22000:2326:2327:10355
+BBC 1 Oxford:10817:v:0:22000:2329:2330:10356
+ETV6:10817:v:0:22000:2305:2306:10371
+POP:11426:v:0:27500:2311:2312:52500
+3751 PH:11426:v:0:27500:2311:2312:52501
+Chart Show TV:11426:v:0:27500:2309:2310:52505
+3761 PH:11426:v:0:27500:2313:2314:52512
+The Vault:11426:v:0:27500:2322:2323:52515
+Chase-it.tv:11426:v:0:27500:2318:2319:52520
+OBE:11426:v:0:27500:2307:2308:52525
+Tiny Pop:11426:v:0:27500:2316:2317:52530
+Spice Extreme:11426:v:0:27500:2320:2321:52561
+Climax3 - 1:11426:v:0:27500:2324:2325:52562
+Climax3 - 2:11426:v:0:27500:2326:2327:52563
+Climax3 - 3:11426:v:0:27500:2328:2329:52564
+Adult Channel:11426:v:0:27500:2330:2331:52565
+Playboy TV:11426:v:0:27500:2313:2314:52566
+52567:11426:v:0:27500:2330:2331:52567
+3911 PH:11426:v:0:27500:2320:2321:52581
+Simply Home:11488:v:0:27500:2364:2365:50102
+DTPCad4:11488:v:0:27500:2315:2316:50103
+Shop Vector:11488:v:0:27500:2322:2323:50105
+Simply Ideas:11488:v:0:27500:2324:2325:50115
+Simply Shop.:11488:v:0:27500:2353:2354:50120
+JobsTV:11488:v:0:27500:2366:2367:50125
+GayDateTV:11488:v:0:27500:2361:2362:50130
+Motors TV:11488:v:0:27500:3329:3330:50135
+nation217:11488:v:0:27500:2329:2330:50170
+52536:11488:v:0:27500:2353:2354:50176
+3786 PH:11488:v:0:27500:2342:2343:50177
+Avago Roulette:11488:v:0:27500:0:0:50180
+50181:11488:v:0:27500:2353:2354:50181
+XplicitXXX:11488:v:0:27500:0:0:50175
+3901 PH:11584:h:0:27500:2348:2349:50101
+50621:11584:h:0:27500:0:0:50621
+Gay TV:11584:h:0:27500:2333:2334:50671
+Red Hot Films:11584:h:0:27500:2338:2339:50672
+Red Hot Euro:11584:h:0:27500:2336:2337:50673
+Television X 2:11584:h:0:27500:2326:2327:50674
+Television X 3:11584:h:0:27500:2314:2315:50675
+Television X:11584:h:0:27500:2306:2307:50676
+RedHot All Girl:11584:h:0:27500:2340:2341:50677
+ExpressShop.:11584:h:0:27500:2331:2332:50678
+Real Estate TV:11584:h:0:27500:2329:2330:50679
+Red Hot Only 18:11584:h:0:27500:2311:2312:50680
+Red Hot Wives:11584:h:0:27500:2344:2345:50681
+RH 40+ Wives:11584:h:0:27500:2346:2347:50682
+redhot amateur:11584:h:0:27500:2342:2343:50683
+redhot uktalent:11584:h:0:27500:0:0:50100
+50686:11584:h:0:27500:0:0:50686
+AvaTest:11546:h:0:27500:2319:2320:50446
+SFI:11546:h:0:27500:0:0:50455
+Shop on TV:11546:h:0:27500:2315:2316:50400
+Thane Direct:11546:h:0:27500:2317:2318:50405
+AVAGO:11546:h:0:27500:2319:2320:50410
+SouthForYou:11546:h:0:27500:2313:2314:50420
+Stop + Shop:11546:h:0:27500:2324:2325:50430
+VHR:11546:h:0:27500:2326:2327:50435
+ditg:11546:h:0:27500:0:0:50439
+cso:11546:h:0:27500:2331:2332:50440
+Channel 425:11546:h:0:27500:2355:2357:50445
+Thomas Cook:11526:v:0:27500:2312:2313:50300
+B4:11526:v:0:27500:2361:2362:50305
+Al Jazeera:11526:v:0:27500:2310:2311:50325
+NHS 1:11526:v:0:27500:2314:2315:50370
+NHS 2:11526:v:0:27500:0:2329:50371
+NHS 2:11526:v:0:27500:0:2337:50372
+NHS Direct Interactive:11526:v:0:27500:0:0:50373
+NHS 4:11526:v:0:27500:2345:2347:50374
+SAB TV:11388:h:0:27500:2310:2311:52401
+Performance:11388:h:0:27500:2312:2313:52402
+channel U:11388:h:0:27500:2314:2315:52403
+Gems.tv:11388:h:0:27500:2317:2318:52404
+Soundtrack ch.:11388:h:0:27500:2307:2308:52405
+HorrorChannel:11388:h:0:27500:2342:2343:52406
+Chat Box:11388:h:0:27500:2319:2320:52407
+Golf Channel:11388:h:0:27500:2321:2322:52408
+Ex&Mart TV:11388:h:0:27500:2323:2324:52409
+TVW Select:11388:h:0:27500:2305:2306:52412
+Game In TV:11388:h:0:27500:2335:2336:52414
+Majestic TV:11388:h:0:27500:2340:2341:52415
+52421:11388:h:0:27500:0:0:52421
+18PlusXXX:11388:h:0:27500:0:0:52410
+XXXHousewive:11388:h:0:27500:0:0:52411
+Open Access 2:11642:v:0:27500:2312:2318:50152
+Unlimited TV:11642:v:0:27500:2319:2320:50153
+Racing UK:11642:v:0:27500:2306:2313:50951
+Vectone Bangla:11642:v:0:27500:2325:2326:50952
+VECTONE Urdu:11642:v:0:27500:2328:2329:50953
+VECTONE Tamil:11642:v:0:27500:2331:2332:50954
+VECTONE Bolly:11642:v:0:27500:2334:2335:50955
+Open Access:11642:v:0:27500:2356:2357:50956
+Classic FM TV:11642:v:0:27500:2358:2359:50957
+50959:11642:v:0:27500:2314:2315:50959
+Extreme Sports:11680:v:0:27500:2307:2308:51101
+EuroNews:11680:v:0:27500:2310:2311:51102
+GOD Channel:11680:v:0:27500:2319:2320:51103
+GOD REVIVAL:11680:v:0:27500:2321:2322:51104
+CrossRhythm:11680:v:0:27500:0:2306:51106
+Life TV:11680:v:0:27500:2323:2324:51108
+TBN Europe:11680:v:0:27500:2325:2326:51109
+HollywoodTV:11680:v:0:27500:2327:2328:51112
+GOD 2:11680:v:0:27500:2321:2322:51115
+revelation:11680:v:0:27500:2339:2340:51116
+Live XXX TV:11680:v:0:27500:0:0:51113
+51117:11680:v:0:27500:0:0:51117
+Alphameric1:11680:v:0:27500:0:0:51121
+Alphameric2:11680:v:0:27500:0:0:51122
+CFC TV:11680:v:0:27500:0:0:51105
+mta-muslim tv:11661:h:0:27500:2311:2312:51001
+BEN:11661:h:0:27500:2327:2328:51008
+Abu Dhabi TV:11661:h:0:27500:2329:2330:51009
+TV Travelshop 2:11661:h:0:27500:2370:2371:51010
+CCTV-9:11661:h:0:27500:2333:2334:51011
+Islam Channel:11661:h:0:27500:2337:2338:51014
+51020:11661:h:0:27500:0:2339:51020
+PlayMonteCarlo & Roulette:11661:h:0:27500:0:2319:51022
+2gbstp:11661:h:0:27500:0:0:51013
+Tel Sell:11623:h:0:27500:2319:2320:50832
+mSync:11623:h:0:27500:0:0:50837
+NASN:11623:h:0:27500:2322:2323:50839
+Classics TV:11623:h:0:27500:2324:2325:50840
+Information TV:11623:h:0:27500:2326:2327:50841
+Wrestling Chnl:11623:h:0:27500:2329:2330:50842
+TWC Reloaded:11623:h:0:27500:2331:2332:50843
+FRIENDLY TV:11623:h:0:27500:2333:2334:50848
+McColls:11623:h:0:27500:0:2335:50851
+Moto:11623:h:0:27500:0:2336:50852
+Teds FM:11623:h:0:27500:0:2337:50853
+Topps FM:11623:h:0:27500:0:2338:50855
+Kiss:11623:h:0:27500:0:2339:50856
+Smash Hits!:11623:h:0:27500:0:2340:50857
+Kerrang:11623:h:0:27500:0:2341:50858
+The Hits:11623:h:0:27500:0:2342:50859
+Magic:11623:h:0:27500:0:2343:50860
+Q:11623:h:0:27500:0:2344:50861
+MOJO:11623:h:0:27500:0:2345:50862
+Heat:11623:h:0:27500:0:2346:50863
+GlobeCast:11623:h:0:27500:0:2347:50864
+PTV Prime:11623:h:0:27500:2315:2316:50865
+Fashion TV:11623:h:0:27500:0:0:50850
+ITV1 London:10832:h:0:22000:2305:2307:10000
+ITV News:10832:h:0:22000:2329:2336:10009
+ITV1 Central:10832:h:0:22000:2327:2328:10010
+ITV1 HTV Wales:10832:h:0:22000:2334:2335:10020
+ITV1 HTV West:10832:h:0:22000:2341:2342:10030
+ITV1 W Country:10832:h:0:22000:2348:2349:10040
+G49:10832:h:0:22000:2334:2335:10099
+ITV1 Anglia:10891:h:0:22000:2305:2306:10100
+ITV1 Border:10891:h:0:22000:2327:2328:10110
+ITV1 BorderSco:10891:h:0:22000:2334:2335:10120
+ITV1 Meridian S:10891:h:0:22000:2348:2349:10140
+ITV1 Meridian E:10891:h:0:22000:2341:2342:10141
+ITV1 Tyne Tees:10891:h:0:22000:2355:2356:10150
+ITV1 Yorkshire:10891:h:0:22000:2362:2363:10160
+G53:10891:h:0:22000:2334:2335:10199
+ITV Channel Is:10906:v:0:22000:2326:2328:10200
+Grampian TV:10906:v:0:22000:2333:2334:10210
+Scottish TV:10906:v:0:22000:2340:2341:10220
+UTV:10906:v:0:22000:2347:2348:10230
+ITV2:10906:v:0:22000:2350:2351:10240
+ITV1 Granada:10906:v:0:22000:2305:2306:10250
+ITV3:10906:v:0:22000:2363:2364:10260
+G54:10906:v:0:22000:2357:2358:10299
+6300:10758:v:0:22000:2305:2306:10119
+LONDON TV:11222:h:0:27500:2334:2335:52014
+Setanta Sports:11222:h:0:27500:0:0:52021
+Setanta Sports:11222:h:0:27500:0:0:52022
+Pure Dance:11222:h:0:27500:0:2312:52025
+Club Asia:11222:h:0:27500:0:2305:52026
+Setanta PPV2:11222:h:0:27500:0:0:52032
+[fffe]:11222:h:0:27500:0:0:65534
+UCB TV:11222:h:0:27500:2313:2314:52001
+ATN:11222:h:0:27500:2310:2311:52002
+Overload:11222:h:0:27500:2306:2307:52003
+Golf Pro-Shop:11222:h:0:27500:2315:2316:52004
+You TV:11222:h:0:27500:2336:2337:52005
+Escape:11222:h:0:27500:2317:2318:52006
+52007:11222:h:0:27500:2324:2325:52007
+Get Lucky TV:11222:h:0:27500:2319:2320:52008
+Wonderful:11222:h:0:27500:2308:2309:52009
+Musicians Chnl:11222:h:0:27500:2326:2327:52010
+Rangers TV:11222:h:0:27500:2328:2329:52011
+Celtic TV:11222:h:0:27500:2330:2331:52012
+Advert Channel:11222:h:0:27500:2332:2333:52013
+E4+1:10729:v:0:22000:2306:2307:8300
+3310:10729:v:0:22000:2317:2318:8310
+3315:10729:v:0:22000:0:0:8315
+3320:10729:v:0:22000:0:0:8320
+[fffe]:11264:h:0:22000:0:0:65534
+52101:11264:h:0:22000:2305:2306:52101
+52102:11264:h:0:22000:2307:2308:52102
+52103:11264:h:0:22000:2309:2310:52103
+52104:11264:h:0:22000:2311:2312:52104
+IDMT:11307:h:0:27500:2307:2308:52200
+ Broadband UK:11307:h:0:27500:2305:2306:52210
+52220:11307:h:0:27500:2309:2310:52220
+Trouble Reload:11307:h:0:27500:2311:2312:52230
+Challenge+1:11307:h:0:27500:2314:2315:52232
+Ftn:11307:h:0:27500:0:0:52231
diff --git a/util/szap/channels-conf/dvb-s/BrasilSat-B3-84.0W b/util/szap/channels-conf/dvb-s/BrasilSat-B3-84.0W
new file mode 100644
index 0000000..b3632bb
--- /dev/null
+++ b/util/szap/channels-conf/dvb-s/BrasilSat-B3-84.0W
@@ -0,0 +1,39 @@
+NoName:3675:v:0:4285:1110:1211:1
+Rede 21:3688:v:0:2308:308:256:1
+SNG#3 TERRA VIVA:3692:v:0:3200:308:256:1
+TV PONTA PORA :3697:v:0:3333:1110:1211:1
+Servico 1:3710:v:0:12960:36:37:1
+TV Assembleia:3710:v:0:12960:39:40:2
+Servico 3:3710:v:0:12960:42:43:3
+TV Cultura:3710:v:0:12960:33:34:4
+TV Ra-Tim-Bum:3710:v:0:12960:45:46:5
+Tv Morena:3738:v:0:4710:4096:4097:1
+[6d65]:3754:v:0:5000:0:0:28005
+[6dc9]:3754:v:0:5000:0:0:28105
+[0faa]:3754:v:0:5000:0:0:4010
+[0fb4]:3754:v:0:5000:0:0:4020
+[6d61]:3754:v:0:5000:0:0:28001
+[0f9f]:3754:v:0:5000:0:0:3999
+[0fbe]:3754:v:0:5000:0:0:4030
+[000b]:3754:v:0:5000:0:0:11
+[5014]:3754:v:0:5000:0:0:20500
+STV:3768:v:0:8000:160:80:1
+CANAL 2:3768:v:0:8000:161:84:2
+TELECONF:3768:v:0:8000:162:88:3
+REDETV RO:3805:v:0:3255:4194:4195:1
+Videocom:3858:v:0:4289:1110:1211:1
+TVSULBAHIA:3911:v:0:3255:33:36:2
+TV ARATU BA:3927:v:0:3255:33:36:2
+TV BAND BA:3931:h:0:3255:337:340:21
+TV BAND BA:3932:v:0:3255:337:340:21
+REDE SUPER:3940:v:0:3255:337:340:1
+RBI:3949:v:0:4340:337:340:33
+TV TRIBUNA:3955:v:0:4340:337:340:1
+5 :3970:v:0:4445:1160:1120:1
+TV EDUCATIVA MS:4013:v:0:3255:337:340:33
+TV Justica:4060:v:0:3330:289:290:1
+CNT GERACAO 1:4075:v:0:4444:289:290:20101
+ASS-LEG-SC:4132:v:0:2532:337:340:33
+EMBRATEL 21:4152:v:0:2300:257:514:1
+SEXY TV:4155:v:0:2170:257:258:1
+BASA:4169:v:0:8140:4141:4140:4
diff --git a/util/szap/channels-conf/dvb-t/au-Adelaide b/util/szap/channels-conf/dvb-t/au-Adelaide
new file mode 100644
index 0000000..fc97071
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/au-Adelaide
@@ -0,0 +1,28 @@
+ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:592
+ABC TV Adelaide:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:593
+ABC TV 2:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:594
+ABC TV 3:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:595
+ABC TV 4:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:596
+ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2311:598
+7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1281:1282:1360
+7 Digital 1:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1281:1282:1361
+7 Digital 2:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1281:1282:1362
+7 Digital 3:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1281:1282:1363
+7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1345:1346:1364
+NINE Digital:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1105
+NINE HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:513:0:1112
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1617
+TEN Digital 1:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1618
+TEN Digital 2:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1619
+TEN Digital 3:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1620
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1621
+TEN Digital 4:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1622
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1623
+TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1624
+Ten Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1625
+SBS HD:564500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:832
+SBS DIGITAL 1:564500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:833
+SBS DIGITAL 2:564500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:834
+SBS EPG:564500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:835
+SBS RADIO 1:564500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:846
+SBS RADIO 2:564500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:847
diff --git a/util/szap/channels-conf/dvb-t/au-Brisbane b/util/szap/channels-conf/dvb-t/au-Brisbane
new file mode 100644
index 0000000..5eb0853
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/au-Brisbane
@@ -0,0 +1,29 @@
+ABC HDTV:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:576
+ABC TV Brisbane:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:577
+ABC TV 2:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:578
+ABC TV 3:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:579
+ABC TV 4:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:580
+ABC DiG Radio:226500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2310:582
+7 Digital:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1025:1026:1344
+7 Digital 1:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1025:1026:1345
+7 Digital 2:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1025:1026:1346
+7 Digital 3:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1025:1026:1347
+7 HD Digital:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1089:1090:1348
+Nine Digital:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:513:660:1025
+Nine Guide:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:517:660:1030
+Nine High Definition:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1152
+TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1601
+TEN Digital 1:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1602
+TEN Digital 2:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1603
+TEN Digital 3:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1604
+TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1605
+TEN Digital 4:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1606
+TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1607
+TEN HD:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1608
+TEN Digital:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1609
+SBS HD:585625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:816
+SBS DIGITAL 1:585625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:817
+SBS DIGITAL 2:585625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:818
+SBS EPG:585625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:819
+SBS RADIO 1:585625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:830
+SBS RADIO 2:585625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:831
diff --git a/util/szap/channels-conf/dvb-t/au-Hobart b/util/szap/channels-conf/dvb-t/au-Hobart
new file mode 100644
index 0000000..80edcb0
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/au-Hobart
@@ -0,0 +1,18 @@
+ABC HDTV:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2314:0:624
+ABC TV Hobart:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:625
+ABC2:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2309:2310:626
+ABC TV:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:627
+ABC DiG Radio:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2317:630
+ABC DiG Jazz:191625000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2318:631
+SBS HD:205500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:848
+SBS DIGITAL 1:205500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:849
+SBS DIGITAL 2:205500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:850
+SBS EPG:205500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:851
+SBS RADIO 1:205500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:862
+SBS RADIO 2:205500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:863
+SCT Hobart:212500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:625:626:2306
+SCT - HD:212500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:3611:0:2338
+WIN TELEVISION:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:116:117:1
+WIN HD:184500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:129:130:10
+TDT - SD:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:657:658:2071
+TDT - HD:219500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:3511:0:2103
diff --git a/util/szap/channels-conf/dvb-t/au-Melbourne b/util/szap/channels-conf/dvb-t/au-Melbourne
new file mode 100644
index 0000000..0b0542f
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/au-Melbourne
@@ -0,0 +1,17 @@
+ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:2308:560
+ABC TV Melbourne:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561
+ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2310:566
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1585
+TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1592
+Nine Digital:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:519:720:1072
+Nine Digital HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1073
+Nine Guide:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:517:700:1074
+7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1328
+7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:833:834:1332
+7 Program Guide:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:865:866:1334
+SBS HD:536625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:784
+SBS DIGITAL 1:536625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
+SBS DIGITAL 2:536625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
+SBS EPG:536625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:787
+SBS RADIO 1:536625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798
+SBS RADIO 2:536625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799
diff --git a/util/szap/channels.conf-dvbt-australia b/util/szap/channels-conf/dvb-t/au-Sydney-NorthShore
index 9709b0b..60e599d 100644
--- a/util/szap/channels.conf-dvbt-australia
+++ b/util/szap/channels-conf/dvb-t/au-Sydney-NorthShore
@@ -1,31 +1,31 @@
-ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:560
-ABC TV Melbourne:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561
-ABC TV 2:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:562
-ABC TV 3:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563
-ABC TV 4:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:564
-ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2311:566
-TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1585
-TEN Digital 1:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1586
-TEN Digital 2:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1587
-TEN Digital 3:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1588
-TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1589
-TEN Digital 4:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1590
-TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1591
-TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1592
-TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1593
-Nine Digital:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:513:660:1072
-Nine Digital HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1073
-Nine Guide:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:670:1074
-7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1328
-7 Digital 1:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1329
-7 Digital 2:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1330
-7 Digital 3:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1331
-7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:833:834:1332
-7 Program Guide:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:865:866:1334
-SBS HD:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:784
-SBS DIGITAL 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
-SBS DIGITAL 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
-SBS EPG:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:787
-SBS RADIO 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798
-SBS RADIO 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799
-
+ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:544
+ABC TV Sydney:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:545
+ABC TV 2:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:546
+ABC TV 3:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:547
+ABC TV 4 :226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:548
+ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2310:550
+Test.:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:0:549
+7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:513:514:1312
+7 Digital 1:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:513:514:1313
+7 Digital 2:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:513:514:1314
+7 Digital 3:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:513:514:1315
+7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:577:578:1316
+Program Guide:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:609:610:1318
+NINE DIGITAL:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:519:720:1
+NINE HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:5
+NINE GUIDE:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:517:720:6
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1569
+TEN Digital 1:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1570
+TEN Digital 2:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1571
+TEN Digital 3:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1572
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1573
+TEN Digital 4:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1574
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1575
+TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1576
+Ten Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1577
+SBS HD:571500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:768
+SBS DIGITAL 1:571500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:769
+SBS DIGITAL 2:571500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:770
+SBS EPG:571500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:772
+SBS RADIO 1:571500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:782
+SBS RADIO 2:571500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:783
diff --git a/util/szap/channels-conf/dvb-t/cz-Praha b/util/szap/channels-conf/dvb-t/cz-Praha
new file mode 100644
index 0000000..4a5c16c
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/cz-Praha
@@ -0,0 +1,16 @@
+CT2.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:512:650:1
+Nova.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:513:661:2
+CT1.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:2325:2326:3
+Prima.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:514:671:4
+Stanice O.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:2322:2323:5
+Radiozurnal.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:652:6
+Praha.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:653:7
+Vltava.:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:651:8
+iTV:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:9
+Prima:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:161:84:1
+CT2:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:164:96:4
+TV Program:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2501:2502:5
+RADIO2:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2832:6
+RADIO:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2831:9
+Proglas:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:180:11
+Nova.:674000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:205:206:3
diff --git a/util/szap/channels-conf/dvb-t/de-Berlin b/util/szap/channels-conf/dvb-t/de-Berlin
new file mode 100644
index 0000000..69cd114
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Berlin
@@ -0,0 +1,47 @@
+rbb Brandenburg:522000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1101:1102:11
+rbb Berlin:522000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1201:1202:12
+Phoenix:522000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1301:1302:13
+Das Erste:522000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1401:1402:14
+ARD-MHP-Data:522000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16
+ZDF:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:545:546:514
+Info/3sat:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:561:562:515
+Doku/KiKa:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:593:594:517
+SAT.1:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:385:386:16408
+N24:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:225:226:16398
+ProSieben:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:305:306:16403
+KABEL1:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:162:16394
+MDR FERNSEHEN:191500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:101:102:1
+ARD-Online-Kanal:191500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:10
+ARD-MHP-Data:191500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:9
+NDR FERNSEHEN:191500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:301:302:3
+arte:191500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:201:202:2
+Test Programm:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:3841:3842:16624
+SUD enhanced:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16650
+13 TH STREET:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:4273:4274:16651
+BMCO Nokia IPDC Signalling:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16652
+BMCO Nokia IPDC 1:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16653
+BMCO Nokia IPDC 2:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16654
+BMCO Nokia IPDC 3:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16655
+IP Services:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16640
+Media Broadcast Services:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16641
+SUD:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16642
+SUD 1:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16643
+Kathrein Download:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16644
+HUMAX DOWNLOAD SVC:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16645
+BMCO Nokia IPDC 4:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16656
+BMCO Nokia IPDC 5:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16657
+BMCO Nokia IPDC 6:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16658
+BMCO Nokia IPDC 7:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16659
+BMCO Nokia IPDC 8:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16660
+RTL:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:337:338:16405
+RTL2:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:353:354:16406
+Super RTL:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:433:434:16411
+VOX:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:545:546:16418
+Südwest BW/RP:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:257:258:16
+WDR:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:241:242:15
+BBC World:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:49:50:16387
+FAB:177500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:3073:3074:16576
+DSF:754000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:129:130:16392
+Testkanal NEUN LIVE:754000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:273:274:16401
+VIVA Plus:754000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:529:530:16417
+Eurosport:754000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:577:578:16420
diff --git a/util/szap/channels-conf/dvb-t/de-Braunschweig b/util/szap/channels-conf/dvb-t/de-Braunschweig
new file mode 100644
index 0000000..28fb4a6
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Braunschweig
@@ -0,0 +1,25 @@
+arte:198500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4385:4386:2
+Phoenix:198500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4401:4402:3
+EinsExtra:198500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4417:4418:4
+Das Erste:198500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4369:4370:128
+ZDF:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:514
+Info/3sat:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:561:562:515
+Doku/KiKa:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:593:594:517
+RTL Television:498000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:337:338:16405
+RTL2:498000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:353:354:16406
+Super RTL:498000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:369:370:16407
+VOX:498000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:16418
+hr-fernsehen:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4673:4674:65
+MDR FERNSEHEN:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4657:4658:100
+NDR FS NDS:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:129
+NDR FS HH *:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:130
+NDR FS SH *:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:131
+NDR FS MVP *:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:132
+WDR Köln:594000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4641:4642:262
+SAT.1:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:385:386:16408
+N24:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:225:226:16398
+ProSieben:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:305:306:16403
+KABEL1:658000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:162:16394
+Eurosport:786000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:577:578:16420
+TERRA NOVA:786000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:609:610:16422
+TELE 5:786000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:465:466:16413
diff --git a/util/szap/channels-conf/dvb-t/de-Bremen b/util/szap/channels-conf/dvb-t/de-Bremen
new file mode 100644
index 0000000..0826f31
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Bremen
@@ -0,0 +1,25 @@
+arte:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:202:2
+Phoenix:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:3
+NDR RB:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:518:519:161
+Das Erste RB:482000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:261:262:160
+hr-fernsehen:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4673:4674:65
+MDR FERNSEHEN:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4657:4658:100
+NDR FS NDS:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:129
+NDR FS HH *:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:130
+NDR FS SH *:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:131
+NDR FS MVP *:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:132
+WDR Köln:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4641:4642:262
+ZDF:562000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:514
+Info/3sat:562000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:561:562:515
+Doku/KiKa:562000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:593:594:517
+RTL Television:642000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:337:338:16405
+RTL2:642000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:353:354:16406
+Super RTL:642000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:369:370:16407
+VOX:642000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:16418
+Eurosport:666000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:577:578:16420
+TERRA NOVA:666000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:609:610:16422
+TELE 5:666000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:465:466:16413
+SAT.1:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:385:386:16408
+N24:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:225:226:16398
+ProSieben:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:305:306:16403
+KABEL1:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:162:16394
diff --git a/util/szap/channels-conf/dvb-t/de-Koeln-Bonn b/util/szap/channels-conf/dvb-t/de-Koeln-Bonn
new file mode 100644
index 0000000..199ca85
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Koeln-Bonn
@@ -0,0 +1,23 @@
+RTL Television:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:337:338:16405
+RTL2:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:353:354:16406
+Super RTL:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:433:434:16411
+VOX:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:16418
+ZDF:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:514
+Info/3sat:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:561:562:515
+Doku/KiKa:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:593:594:517
+MDR Fernsehen:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4657:4658:100
+NDR FS NDS:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4641:4642:129
+SÃœDWEST RP:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4673:4674:226
+WDR Köln:698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4625:4626:262
+N24:650000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:225:226:16398
+ProSieben:650000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:305:306:16403
+KABEL1:650000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:162:16394
+SAT.1:650000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2078:2077:16408
+arte:826000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4385:4386:2
+Phoenix:826000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4401:4402:3
+EinsMuXx:826000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4417:4418:6
+Das Erste:826000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4369:4370:256
+Eurosport:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:577:578:16420
+VIVA:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:513:514:16416
+TERRA NOVA:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:609:610:16422
+CNN Int.:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:97:98:16390
diff --git a/util/szap/channels-conf/dvb-t/de-Leipzig b/util/szap/channels-conf/dvb-t/de-Leipzig
new file mode 100644
index 0000000..9173a6f
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Leipzig
@@ -0,0 +1,7 @@
+# channels.conf for DVB-T - Leipzig (Germany) Transmitter
+# Generated by Albrecht Lohoefener <albrechtloh@gmx.de>
+
+MDR:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1553:1554:97
+rbb:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:2833:2834:177
+WDR:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:4193:4194:262
+BR:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:529:530:33
diff --git a/util/szap/channels-conf/dvb-t/de-Luebeck b/util/szap/channels-conf/dvb-t/de-Luebeck
new file mode 100644
index 0000000..257f139
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Luebeck
@@ -0,0 +1,22 @@
+ZDF:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:545:546:514
+Info/3sat:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:561:562:515
+Doku/KiKa:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:593:594:517
+Bayerisches Fernsehen:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5185:5186:34
+MDR FERNSEHEN:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5169:5170:100
+NDR FS NDS *:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5137:5138:129
+NDR FS HH *:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5137:5138:130
+NDR FS SH:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5137:5138:131
+NDR FS MVP *:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5137:5138:132
+WDR Köln:530000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:5153:5154:262
+N24:546000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:225:226:16398
+ProSieben:546000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:305:306:16403
+KABEL1:546000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:161:162:16394
+SAT.1:546000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_1_2:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:385:386:16408
+arte:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4385:4386:2
+Phoenix:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4401:4402:3
+EinsExtra:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4417:4418:4
+Das Erste:570000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4369:4370:128
+RTL Television:626000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:337:338:16405
+RTL2:626000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:353:354:16406
+Super RTL:626000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:369:370:16407
+VOX:626000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:16418
diff --git a/util/szap/channels-conf/dvb-t/de-Rhein-Main b/util/szap/channels-conf/dvb-t/de-Rhein-Main
new file mode 100644
index 0000000..32d4edc
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Rhein-Main
@@ -0,0 +1,6 @@
+c8:198500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
+c22:482000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
+c34:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
+c54:738000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
+c57:762000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
+c64:818000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
diff --git a/util/szap/channels-conf/dvb-t/de-Ruhrgebiet b/util/szap/channels-conf/dvb-t/de-Ruhrgebiet
new file mode 100644
index 0000000..029dcd7
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/de-Ruhrgebiet
@@ -0,0 +1,46 @@
+# channels.conf for dvb-t in germany, broadcasting area 'Duesseldorf/Ruhrgebiet'.
+# see
+# http://nrw.ueberallfernsehen.de/fileadmin/downloads/Programm_Ruhr_2005_04_04_final.pdf
+# for details on the regional availability of some channels (see the comments below).
+#
+RTL Television:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:337:338:16405
+RTL2:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:353:354:16406
+Super RTL:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:433:434:16411
+VOX:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:16418
+ZDF:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:545:546:514
+Info/3sat:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:561:562:515
+Doku/KiKa:586000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:593:594:517
+CNN Int.:722000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:97:98:16390
+VIVA:722000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:513:514:16416
+Eurosport:722000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:577:578:16420
+TERRA NOVA:722000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:609:610:16422
+ProSieben:746000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:305:306:16403
+SAT.1:746000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:385:386:16408
+KABEL1:746000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:162:16394
+N24:746000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:225:226:16398
+arte:818000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4385:4386:2
+Phoenix:818000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4401:4402:3
+EinsMuXx:818000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4417:4418:6
+Das Erste:818000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4369:4370:256
+##
+### regionale Sender/regional channels
+##
+## Kanal 25; Senderstandorte/broadcasting locations: Langenberg, Dortmund
+MDR FERNSEHEN-25:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5425:5426:100
+NDR FS NDS-25:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5409:5410:129
+SUEDWEST RP-25:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5441:5442:226
+WDR Dortmund-25:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5393:5394:259
+WDR Essen-25:506000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5393:5394:261
+#
+## Kanal 46; Senderstandorte/broadcasting locations: Duesseldorf, Wesel, Langenberg
+MDR FERNSEHEN-46:674000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4913:4914:100
+NDR FS NDS-46:674000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4897:4898:129
+SUEDWEST RP-46:674000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4929:4930:226
+WDR Duesseldorf-46:674000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4881:4882:260
+WDR Wuppertal-46:674000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4881:4882:265
+## Kanal 59; Senderstandorte/broadcasting locations: Essen
+MDR FERNSEHEN-59:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5169:5170:100
+NDR FS NDS-59:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5153:5154:129
+SUEDWEST RP-59:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5185:5186:226
+WDR Dortmund-59:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5137:5138:259
+WDR Essen-59:778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:5137:5138:261
diff --git a/util/szap/channels-conf/dvb-t/es-Alpicat b/util/szap/channels-conf/dvb-t/es-Alpicat
new file mode 100644
index 0000000..e69158c
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/es-Alpicat
@@ -0,0 +1,19 @@
+#channels.conf for DVB-T - Alpicat (Lleida) Transmitter
+
+#C42
+TV3:642000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:111:112:801
+K3/33:642000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:121:122:802
+3/24:642000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:131:132:803
+Canal Pilot:642000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:141:142:804
+3XL.net:642000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:151:152:805
+
+#C58
+TVE 1:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:1377
+TVE 2:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:203:1441
+ANTENA 3:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:303:1121
+CANAL+:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:501:503:1057
+TELECINCO:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:403:1185
+
+#C66
+Veo TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:1536
+Net TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:402:1825
diff --git a/util/szap/channels.conf-dvbt-collserola b/util/szap/channels-conf/dvb-t/es-Collserola
index 63456b2..9a1ec85 100644
--- a/util/szap/channels.conf-dvbt-collserola
+++ b/util/szap/channels-conf/dvb-t/es-Collserola
@@ -1,11 +1,11 @@
#channels.conf for DVB-T - Collserola (Barcelona) Transmitter
#C43
-TV3:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:111:112:801
-K3/33:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:121:122:802
-3/24:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:131:132:803
-Canal Pilot:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:141:142:804
-3XL.net:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:151:152:805
+TV3:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:111:112:801
+K3/33:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:121:122:802
+3/24:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:131:132:803
+Canal Pilot:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:141:142:804
+3XL.net:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:151:152:805
#C61
TVE 1:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:1377
@@ -17,9 +17,3 @@ TELECINCO:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSM
#C66
Veo TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:1536
Net TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:402:1825
-Video Promocional 1:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:210:212:425
-Video Promocional 2:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:110:0:420
-[1388]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5000
-[138c]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5004
-[138a]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5002
-
diff --git a/util/szap/channels-conf/dvb-t/es-Madrid b/util/szap/channels-conf/dvb-t/es-Madrid
new file mode 100644
index 0000000..7066e7b
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/es-Madrid
@@ -0,0 +1,26 @@
+TVE 1:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:380
+TVE 2:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:203:381
+24H TVE:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1001:1003:382
+RNE1:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:2001:385
+RNEC:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:2011:386
+CLAN/50 TVE:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1501:1503:383
+RNE3:770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:2021:387
+TM3:810000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:111:113:421
+LAOTRA:810000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:211:212:422
+ONDA6:810000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:311:312:423
+TELEDEPORTE:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:100
+VEO TV:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1001:1002:260
+VEO 2:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:261
+NET TV:834000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1501:1502:300
+CUATRO:842000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:160:80:1057
+CNN+:842000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:84:1058
+40 LATINO:842000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:162:88:1059
+LA SEXTA 1:842000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1501:0:340
+T5 Estrellas:850000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:301:181
+T5 Sport:850000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:202:302:182
+Telecinco:850000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:203:303:180
+FLYMUSIC:850000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1501:1502:301
+antena 3:858000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:303:140
+a3.neox:858000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:501:503:141
+a3.nova:858000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1001:1003:142
+La Sexta 2:858000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1501:0:341
diff --git a/util/szap/channels-conf/dvb-t/es-Mussara b/util/szap/channels-conf/dvb-t/es-Mussara
new file mode 100644
index 0000000..7962324
--- /dev/null
+++ b/util/szap/channels-conf/dvb-t/es-Mussara
@@ -0,0 +1,19 @@
+#channels.conf for DVB-T - La Mussara (Reus-Tarragona) Transmitter
+
+#C56
+TV3:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:111:112:801
+K3/33:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:121:122:802
+3/24:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:131:132:803
+Canal Pilot:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:141:142:804
+3XL.net:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:151:152:805
+
+#C59
+TVE 1:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:1377
+TVE 2:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:203:1441
+ANTENA 3:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:303:1121
+CANAL+:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:501:503:1057
+TELECINCO:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:403:1185
+
+#C66
+Veo TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:1536
+Net TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:402:1825
diff --git a/util/szap/channels.conf-dvbt-crystal-palace b/util/szap/channels-conf/dvb-t/uk-Crystal-Palace
index 28fa018..a851867 100644
--- a/util/szap/channels.conf-dvbt-crystal-palace
+++ b/util/szap/channels-conf/dvb-t/uk-Crystal-Palace
@@ -65,6 +65,3 @@ jazz fm:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMIS
Kerrang:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1301
Smash Hits:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1201
Kiss:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1101
-
-
-
diff --git a/util/szap/channels.conf-dvbt-hannington b/util/szap/channels-conf/dvb-t/uk-Hannington
index b83620e..b83620e 100644
--- a/util/szap/channels.conf-dvbt-hannington
+++ b/util/szap/channels-conf/dvb-t/uk-Hannington
diff --git a/util/szap/channels.conf-dvbt-oxford b/util/szap/channels-conf/dvb-t/uk-Oxford
index 29a53a2..29a53a2 100644
--- a/util/szap/channels.conf-dvbt-oxford
+++ b/util/szap/channels-conf/dvb-t/uk-Oxford
diff --git a/util/szap/channels.conf-dvbt-reigate b/util/szap/channels-conf/dvb-t/uk-Reigate
index f5fe7cc..f5fe7cc 100644
--- a/util/szap/channels.conf-dvbt-reigate
+++ b/util/szap/channels-conf/dvb-t/uk-Reigate
diff --git a/util/szap/channels.conf-dvbt-sandy_heath b/util/szap/channels-conf/dvb-t/uk-Sandy-Heath
index a0cc632..99dc746 100644
--- a/util/szap/channels.conf-dvbt-sandy_heath
+++ b/util/szap/channels-conf/dvb-t/uk-Sandy-Heath
@@ -10,4 +10,3 @@ C4:665833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_
E4:665833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2831:2832
C5:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018
Shop:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050
-
diff --git a/util/szap/channels.conf-dvbs-astra b/util/szap/channels.conf-dvbs-astra
deleted file mode 100644
index 705f710..0000000
--- a/util/szap/channels.conf-dvbs-astra
+++ /dev/null
@@ -1,226 +0,0 @@
-Das Erste:11837:h:0:27500:101:102:1:28106
-ZDF:11954:h:0:27500:110:120:1:28006
-3sat:11954:h:0:27500:210:220:1:28007
-EinsMuXx:12110:h:0:27500:301:302:1:28203
-EinsFestival:12110:h:0:27500:201:202:1:28202
-EinsExtra:12110:h:0:27500:101:102:1:28201
-MDR FERNSEHEN:12110:h:0:27500:401:402:1:28204
-ORB-Fernsehen:12110:h:0:27500:501:502:1:28205
-B1 Berlin:12110:h:0:27500:601:602:1:28206
-SWR Fernsehen:11837:h:0:27500:801:802:1:28113
-SR Fernsehen Suedwes:11837:h:0:27500:501:502:1:28110
-hessen fernsehen:11837:h:0:27500:301:302:1:28108
-WDR FERNSEHEN:11837:h:0:27500:601:602:1:28111
-Bayerisches FS:11837:h:0:27500:201:202:1:28107
-N3:12110:h:0:27500:2401:2402:1:28224
-BR-alpha:11837:h:0:27500:701:702:1:28112
-KiKa:11954:h:0:27500:310:320:1:28008
-arte:11836:h:0:27500:401:402:1:28109
-ZDF Theaterkanal:11954:h:0:27500:1110:1120:1:28016
-ZDF.info:11954:h:0:27500:610:620:1:28011
-ZDF.doku:11954:h:0:27500:660:670:1:28014
-Phoenix:11837:h:0:27500:901:902:1:28114
-DW-tv:10786:v:0:21997:305:306:1:9005
-RTL Television:12188:h:0:27500:163:104:1:12003
-SAT.1:12480:v:0:27500:1791:1792:1:46
-ProSieben:12480:v:0:27500:255:256:1:898
-RTL2:12188:h:0:27500:166:128:1:12020
-Super RTL:12188:h:0:27500:165:120:1:12040
-KABEL1:12480:v:0:27500:511:512:1:899
-VOX:12188:h:0:27500:167:136:1:12060
-tm3:12480:v:0:27500:767:768:1:897
-Bloomberg TV Germany:12552:v:0:22000:162:99:1:12160
-EuroNews:11954:h:0:27500:2221:2233:1:28015
-N24:12480:v:0:27500:2047:2048:1:47
-n-tv:12670:v:0:22000:162:96:1:12730
-DSF:12480:v:0:27500:1023:1024:1:900
-Eurosport:11954:h:0:27500:410:420:1:28009
-Via 1 - Sch ner Re:12148:h:0:27500:511:512:1:44
-Home Order Tel:12480:v:0:27500:1279:1280:1:40
-QVC GERMANY:12552:v:0:22000:165:166:1:12100
-TW 1:12692:h:0:22000:166:167:1:13013
-Canal Canarias:12441:v:0:27500:513:681:1:29700
-ProSieben A:12051:v:0:27500:161:84:1:20002
-ProSieben CH:12051:v:0:27500:289:290:1:20001
-Kabel 1 Austria:12051:v:0:27500:166:167:1:20004
-Kabel 1 Schweiz:12051:v:0:27500:162:163:1:20003
-CNN Int.:12168:v:0:27500:165:100:1:28512
-Sky News:12552:v:0:22000:305:306:1:3995
-Travel:12168:v:0:27500:163:92:1:28001
-AB SAT / XXL:12266:h:0:27500:164:96:1:17004
-MOTEURS:12266:h:0:27500:160:80:1:17000
-HOT GM:12148:h:0:27500:767:768:1:45
-KTO:12129:v:0:27500:170:120:1:8411
-LA CINQUIEME:12207:v:0:27500:160:80:1:8501
-LCP:12207:v:0:27500:165:100:1:8506
-LibertyTV.com:12611:v:0:22000:941:942:1:12280
-TV5 Europe:12611:v:0:22000:45:46:1:12240
-Motors TV:12611:v:0:22000:191:194:1:12300
-Wishline:12611:v:0:22000:214:216:1:12320
-TV 5:10786:v:0:21997:164:112:1:9001
-RTM - MAROC:10786:v:0:21997:162:96:1:9002
-ESC1 - EGYPTE:10786:v:0:21997:163:104:1:9003
-RAI 1:10786:v:0:21997:289:290:1:9004
-RTPI:10786:v:0:21997:300:301:1:9006
-TV7:10786:v:0:21997:166:128:1:9007
-ARTE:10786:v:0:21997:167:136:1:9009
-Colourbars:12611:v:0:22000:48:49:1:3982
-Alice:12611:v:0:22000:162:96:1:12200
-Video Italia:12611:v:0:22000:121:122:1:12220
-ANDALUCIA TV:11934:v:0:27500:166:104:1:29011
-TVC INT.:12441:v:0:27500:512:660:1:29701
-TV4:11992:h:0:27500:165:98:1:20365
-TV Niepokalanow:11876:h:0:27500:161:82:1:20601
-VIVA:12670:v:0:22000:309:310:1:12732
-VIVA ZWEI:12552:v:0:22000:171:172:1:12120
-MTV Central:12699:v:0:22000:3031:3032:1:28643
-ONYX:12692:h:1:27500:161:84:1:502
-VIVA polska:11603:h:1:27500:190:191:1:611
-DeeJay TV:11603:h:1:27500:160:161:1:602
-NBC:11053:h:1:27500:550:551:1:8008
-EWTN:10722:h:1:29900:1001:1201:1:4601
-MTA INTL:10722:h:1:29900:1004:1204:1:4604
-VOX:11053:h:1:27500:500:501:1:8002
-SAT.1 A:11053:h:1:27500:511:512:1:8003
-RTL2 AUSTRIA:11053:h:1:27500:520:521:1:8004
-ZDF:11053:h:1:27500:570:571:1:8011
-K-TV:11053:h:1:27500:580:581:1:8012
-RTL Television:11053:h:1:27500:160:80:1:8001
-ARTE:11059:v:1:6510:98:99:1:1
-HOT Italia:11095:h:1:27500:4194:4195:1:3714
-Olisat:11095:h:1:27500:33:34:1:3718
-VIVA-POLSKA:11128:h:1:4340:98:99:1:1
-DW-tv:11195:v:1:9099:101:102:1:5301
-Canal 24 Horas:11203:h:1:3999:4130:4131:1:5301
-TV5:11337:v:1:5631:512:640:1:1
-SAT.1 CH:11603:h:1:27500:101:102:1:601
-KurdSat:11603:h:1:27500:111:112:1:603
-ARD "Das Erste":11603:h:1:27500:172:173:1:606
-RTL 2 CH:11603:h:1:27500:175:176:1:609
-Super RTL A:11603:h:1:27500:180:181:1:610
-TV ROMANIA:11622:v:1:27500:227:247:1:10707
-MRTV:11622:v:1:27500:222:242:1:10702
-102.5 HIT Ch:11622:v:1:27500:224:244:1:10704
-TLC SAT:11622:v:1:27500:225:245:1:10705
-PRO-SAT:11622:v:1:27500:246:226:1:10706
-Channel SUN:11622:v:1:27500:229:249:1:10709
-Racing Channel:11622:v:1:27500:228:248:1:10708
-3 ABN:11622:v:1:27500:221:241:1:10701
-Bloom.Germany:11642:h:1:27500:1460:1420:1:4
-Bloomberg TV UK:11642:h:1:27500:1560:1520:1:4
-Sat 7:11642:h:1:27500:1660:1620:1:4
-EDTV 1:11746:h:1:27500:4130:4131:1:9501
-EDTV SPORT:11746:h:1:27500:4386:4387:1:9502
-EDTV BUSINESS:11746:h:1:27500:4642:4643:1:9503
-EDTV DRAMA:11746:h:1:27500:4898:4899:1:9504
-RAI1:11765:v:1:27499:160:80:1:3401
-RAI2:11765:v:1:27499:161:84:1:3402
-RAI3:11765:v:1:27499:162:88:1:3403
-RaiWayTEST2:11765:v:1:27499:516:654:1:3405
-RAIMOSAICO:11765:v:1:27499:518:8191:1:3407
-RAINews24:11803:v:1:27500:516:654:1:3301
-CAMERA DEPUTATI:11803:v:1:27500:517:655:1:3302
-TELEPACE:11803:v:1:27500:515:653:1:3304
-RAISPORTSAT:11803:v:1:27500:512:650:1:3305
-RAINettunoSAT2:11803:v:1:27500:513:651:1:3306
-RAIeducational:11803:v:1:27500:514:652:1:3307
-RAINettunoSAT1:11803:v:1:27500:519:657:1:3308
-SAT2000:11803:v:1:27500:518:656:1:3309
-I1:11918:v:1:27499:512:650:1:1
-C5:11918:v:1:27499:513:660:1:2
-R4:11918:v:1:27499:514:670:1:3
-Telesierra:12091:h:1:27500:4160:4161:1:8704
-C. Milagro:12091:h:1:27500:4368:4369:1:8711
-Italia Sat:12091:h:1:27500:4600:4601:1:8728
-TVE Internacional:12091:h:1:27500:4208:4209:1:8707
-Fiesta:12091:h:1:27500:4432:4433:1:8720
-Retelsat:12091:h:1:27500:4464:4465:1:8722
-ART EUROPE:12013:h:1:27495:164:96:1:450
-EGYPT SAT. CH. 2:12013:h:1:27495:166:104:1:470
-IQRA:12013:h:1:27495:168:112:1:474
-MAURITANIA TV:12110:v:1:27500:230:231:1:704
-ARMENIA TV:12110:v:1:27500:240:241:1:705
-SAILING CHANNEL:12110:v:1:27500:260:261:1:707
-AL JAZEERA:12110:v:1:27500:270:271:1:708
-Coming Soon TV:12110:v:1:27500:310:311:1:717
-SaluteBenessere:12110:v:1:27500:320:321:1:718
-AH-EDP1:12148:v:1:27499:96:97:1:7201
-AH-EDP2:12148:v:1:27499:112:113:1:7202
-Espresso:12148:v:1:27499:192:193:1:7203
-Alice:12148:v:1:27499:160:161:1:7220
-Nuvolari:12148:v:1:27499:176:177:1:7221
-Leonardo:12148:v:1:27499:128:129:1:7222
-AH-EDP3:12148:v:1:27499:36:37:1:7205
-OTE Promo:12187:v:1:27500:517:655:1:1001
-RTS SAT:12187:v:1:27500:519:657:1:1022
-ERT SAT:12187:v:1:27500:514:652:1:1102
-EXTRA:12187:v:1:27500:516:654:1:1106
-TRIAL:12187:v:1:27500:513:651:1:1108
-Minimax:11303:h:1:19540:300:301:1:3
-TVN1:12209:h:1:5631:4194:4195:1:1
-RR TEST:10978:v:1:8998:33:34:1:1
-TV 5 Thailand:10978:v:1:8998:1057:1058:1:2
-TEST-1:10978:v:1:8998:3105:3106:1:4
-FASHION:12244:h:1:27500:123:133:1:103
-AJARA TV:12244:h:1:27500:127:137:1:107
-SLO-TV1:12300:v:1:27495:200:201:1:3201
-POLONIA 1:12302:v:1:27500:205:206:1:3203
-SUPER 1:12302:v:1:27500:207:208:1:3207
-NAPOLI INT.:12302:v:1:27500:240:241:1:3210
-MAGIC:12302:v:1:27500:245:246:1:3211
-COUNTDOWN:12302:v:1:27500:235:236:1:3212
-TBNE:12302:v:1:27500:230:231:1:3213
-NAPOLI CHANNEL:12302:v:1:27500:227:228:1:3215
-KURDISTAN TV:12302:v:1:27500:225:226:1:3214
-ATLAS TV:12379:v:1:27500:3022:3032:1:3002
-TELE 24 SWITZERLAND:12379:v:1:27500:3023:3033:1:3003
-Abu Dhabi TV:12379:v:1:27500:3024:3034:1:3004
-RTV MONTENEGRO:12379:v:1:27500:3026:3036:1:3006
-JAAM-E-JAM 1:12436:h:1:27500:160:80:1:1
-JAAM-E-JAM 2:12436:h:1:27500:161:82:1:2
-SAHAR:12436:h:1:27500:162:84:1:3
-SAHAR 2:12436:h:1:27500:163:86:1:4
-IRINN:12436:h:1:27500:164:88:1:5
-Musicmax:11303:h:1:19540:500:501:1:6
-TEST:12474:h:1:27500:771:8191:1:10608
-EbS:12474:h:1:27500:101:201:1:10601
-MOU.2:12474:h:1:27500:42:43:1:10602
-PINK PLUS:12474:h:1:27500:308:256:1:10605
-LibertyTV.com:12474:h:1:27500:941:942:1:10603
-2M Maroc:12474:h:1:27500:601:602:1:10607
-ZEE TV:12474:h:1:27500:910:911:1:10604
-WorldNet Europe:12483:v:1:8299:4260:4220:1:1
-WorldNet:12483:v:1:8299:4560:4520:1:4
-SICILIA INTERNATIONA:12519:v:1:27499:501:502:1:8309
-SARDEGNA UNO:12519:v:1:27499:503:504:1:8310
-EuroMed:12519:v:1:27499:510:511:1:8312
-TGRT:12519:v:1:27499:505:506:1:8313
-VIDEOLINA:12519:v:1:27499:515:516:1:8318
-MEDIOLANUM:12538:h:1:27500:1131:1132:1:8987
-www.travel:12538:h:1:27500:1180:1183:1:8992
-MonteCarloSat:12538:h:1:27500:5126:5122:1:8877
-Bulgaria TV:12538:h:1:27500:4612:4613:1:8827
-TVN1:12571:h:1:5631:4194:4195:1:1
-JSTV 1:12595:v:1:27500:2000:2001:1:8213
-JSTV 2:12595:v:1:27500:2011:2013:1:8214
-MBC:12595:v:1:27500:160:80:1:8201
-ANN:12595:v:1:27500:161:84:1:8202
-BET:12595:v:1:27500:167:108:1:8208
-EuroNews:12595:v:1:27500:2221:2231:1:8211
-Sharjah Arabs:12653:h:1:27500:1160:1120:1:1
-Qatar Arabs:12653:h:1:27500:1260:1220:1:2
-Saudi 1 Arabs:12653:h:1:27500:1360:1320:1:3
-Kuwait Arabs:12653:h:1:27500:1460:1420:1:4
-Libya Arabs:12653:h:1:27500:1560:1520:1:5
-Sudan Arabs:12653:h:1:27500:1660:1620:1:6
-Oman Arabs:12653:h:1:27500:1760:1720:1:7
-Jordan Arabs:12653:h:1:27500:1860:1820:1:8
-IRAQ TV:12653:h:1:27500:1960:1920:1:9
-Dubai Sport:12653:h:1:27500:1060:1020:1:10
-Digitaly:12672:v:1:27500:220:221:1:4203
-Telemarket:12672:v:1:27500:350:351:1:4211
-eVision:12672:v:1:27500:360:361:1:4214
-Thai TV5:12672:v:1:27500:200:201:1:4201
-Studio Europa:12672:v:1:27500:230:231:1:4204
-Video Italia:12672:v:1:27500:340:341:1:4210
-GAME NETWORK:12672:v:1:27500:291:292:1:4213
diff --git a/util/szap/channels.conf-dvbt-berlin b/util/szap/channels.conf-dvbt-berlin
deleted file mode 100644
index dbddca5..0000000
--- a/util/szap/channels.conf-dvbt-berlin
+++ /dev/null
@@ -1,51 +0,0 @@
-c5:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c7:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c25:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c27:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c33:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c44:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c56:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-c59:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82
-
-SWR BW:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:257:258:16
-WDR:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:241:242:15
-BBC World:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:49:50:16387
-FAB:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:3073:3074:16576
-
-MDR Fernsehen:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:101:102:1
-arte:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:201:202:2
-NDR Fernsehen:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:301:302:3
-
-RTL:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:337:338:16405
-RTL2:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:353:354:16406
-Super RTL:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:433:434:16411
-VOX:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:545:546:16418
-
-Das Erste:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1401:1402:14
-Phoenix:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1301:1302:13
-RBB Berlin:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1201:1202:12
-RBB Brandenburg:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1101:1102:11
-
-ZDF:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:545:546:514
-Info/3sat:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:561:562:515
-Doku/KiKa:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:593:594:517
-
-Kabel 1:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:162:16394
-N24:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:225:226:16398
-ProSieben:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:305:306:16403
-SAT.1:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:385:386:16408
-
-DSF:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:129:130:16392
-Testkanal n-tv:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:273:274:16401
-VIVA Plus:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:529:530:16417
-Eurosport:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:577:578:16420
-
-Testkanal Eurosport:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:577:578:16420
-SUD:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16642
-HUMAX DOWNLOAD SVC:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16645
-IP Services:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16640
-Media Broadcast Services:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16641
-SUD 1:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16643
-Kathrein Download:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16644
-Testkanal MTV:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:193:194:16396
-Testkanal n-tv:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:273:274:16401
diff --git a/util/szap/channels.conf-dvbt-madrid b/util/szap/channels.conf-dvbt-madrid
deleted file mode 100644
index cdf515b..0000000
--- a/util/szap/channels.conf-dvbt-madrid
+++ /dev/null
@@ -1,16 +0,0 @@
-Veo TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:1536
-Net TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:402:1825
-[1388]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5000
-[138c]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5004
-[138a]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5002
-Video Promocional:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:420
-Informe Semanal:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:425
-TVE 2:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:203:1441
-ANTENA 3:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:303:1121
-TELECINCO:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:403:1185
-CANAL+:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:501:503:1057
-TVE 1:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:1377
-Telemadrid:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:111:113:421
-La Otra:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:211:212:422
-Quiero Madrid:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:411:412:424
-Onda 6:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:311:312:423
diff --git a/util/szap/czap.c b/util/szap/czap.c
index 9d183f9..469df56 100644
--- a/util/szap/czap.c
+++ b/util/szap/czap.c
@@ -16,8 +16,9 @@
static char FRONTEND_DEV [80];
static char DEMUX_DEV [80];
+static int exit_after_tuning;
-#define CHANNEL_FILE "/.czap/channels.conf"
+#define CHANNEL_FILE "channels.conf"
#define ERROR(x...) \
do { \
@@ -71,14 +72,17 @@ static const Param modulation_list[] = {
static
-int parse_param(const char *val, const Param * plist, int list_size)
+int parse_param(const char *val, const Param * plist, int list_size, int *ok)
{
int i;
for (i = 0; i < list_size; i++) {
- if (strcasecmp(plist[i].name, val) == 0)
+ if (strcasecmp(plist[i].name, val) == 0) {
+ *ok = 1;
return plist[i].value;
+ }
}
+ *ok = 0;
return -1;
}
@@ -119,6 +123,7 @@ int parse(const char *fname, int list_channels, int chan_no, const char *channel
FILE *f;
char *chan;
char *name, *inv, *fec, *mod;
+ int ok;
if ((f = fopen(fname, "r")) == NULL) {
PERROR("could not open file '%s'", fname);
@@ -144,19 +149,19 @@ int parse(const char *fname, int list_channels, int chan_no, const char *channel
ERROR("cannot parse service data");
return -3;
}
- frontend->inversion = parse_param(inv, inversion_list, LIST_SIZE(inversion_list));
- if (frontend->inversion < 0) {
+ frontend->inversion = parse_param(inv, inversion_list, LIST_SIZE(inversion_list), &ok);
+ if (!ok) {
ERROR("inversion field syntax '%s'", inv);
return -4;
}
- frontend->u.qam.fec_inner = parse_param(fec, fec_list, LIST_SIZE(fec_list));
- if (frontend->u.qam.fec_inner < 0) {
+ frontend->u.qam.fec_inner = parse_param(fec, fec_list, LIST_SIZE(fec_list), &ok);
+ if (!ok) {
ERROR("FEC field syntax '%s'", fec);
return -5;
}
frontend->u.qam.modulation = parse_param(mod, modulation_list,
- LIST_SIZE(modulation_list));
- if (frontend->u.qam.modulation < 0) {
+ LIST_SIZE(modulation_list), &ok);
+ if (!ok) {
ERROR("modulation field syntax '%s'", mod);
return -6;
}
@@ -223,7 +228,7 @@ int setup_frontend(int fe_fd, struct dvb_frontend_parameters *frontend)
static
-int check_frontend (int fe_fd)
+int check_frontend (int fe_fd, int human_readable)
{
fe_status_t status;
uint16_t snr, signal;
@@ -236,9 +241,13 @@ int check_frontend (int fe_fd)
ioctl(fe_fd, FE_READ_BER, &ber);
ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
- printf ("status %02x | signal %04x | snr %04x | "
- "ber %08x | unc %08x | ",
- status, signal, snr, ber, uncorrected_blocks);
+ if (human_readable) {
+ printf ("status %02x | signal %3u%% | snr %3u%% | ber %d | unc %d | ",
+ status, (signal * 100) / 0xffff, (snr * 100) / 0xffff, ber, uncorrected_blocks);
+ } else {
+ printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
+ status, signal, snr, ber, uncorrected_blocks);
+ }
if (status & FE_HAS_LOCK)
printf("FE_HAS_LOCK");
@@ -246,13 +255,16 @@ int check_frontend (int fe_fd)
usleep(1000000);
printf("\n");
+
+ if (exit_after_tuning && (status & FE_HAS_LOCK))
+ break;
} while (1);
return 0;
}
-static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] {<channel name>| -n channel_num}\n"
+static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] [ -H ] {<channel name>| -n channel_num} [-x]\n"
" or: %s [-c conf_file] -l\n\n";
@@ -266,66 +278,78 @@ int main(int argc, char **argv)
int vpid, apid;
int frontend_fd, video_fd, audio_fd;
int opt, list_channels = 0, chan_no = 0;
+ int human_readable = 0;
+
+ while ((opt = getopt(argc, argv, "Hln:hrn:a:f:d:c:x")) != -1) {
+ switch (opt) {
+ case 'a':
+ adapter = strtoul(optarg, NULL, 0);
+ break;
+ case 'f':
+ frontend = strtoul(optarg, NULL, 0);
+ break;
+ case 'd':
+ demux = strtoul(optarg, NULL, 0);
+ break;
+ case 'r':
+ dvr = 1;
+ break;
+ case 'l':
+ list_channels = 1;
+ break;
+ case 'n':
+ chan_no = strtoul(optarg, NULL, 0);
+ break;
+ case 'x':
+ exit_after_tuning = 1;
+ break;
+ case 'H':
+ human_readable = 1;
+ break;
+ case 'c':
+ confname = optarg;
+ break;
+ case '?':
+ case 'h':
+ default:
+ fprintf (stderr, usage, argv[0], argv[0]);
+ return -1;
+ };
+ }
- while ((opt = getopt(argc, argv, "ln:hrn:a:f:d:c:")) != -1) {
- switch (opt) {
- case 'a':
- adapter = strtoul(optarg, NULL, 0);
- break;
- case 'f':
- frontend = strtoul(optarg, NULL, 0);
- break;
- case 'd':
- demux = strtoul(optarg, NULL, 0);
- break;
- case 'r':
- dvr = 1;
- break;
- case 'l':
- list_channels = 1;
- break;
- case 'n':
- chan_no = strtoul(optarg, NULL, 0);
- break;
- case 'c':
- confname = optarg;
- break;
- case '?':
- case 'h':
- default:
- fprintf (stderr, usage, argv[0], argv[0]);
- return -1;
- };
- }
-
- if (optind < argc)
- channel = argv[optind];
-
- if (!channel && chan_no <= 0 && !list_channels) {
- fprintf (stderr, usage, argv[0], argv[0]);
- return -1;
- }
+ if (optind < argc)
+ channel = argv[optind];
+
+ if (!channel && chan_no <= 0 && !list_channels) {
+ fprintf (stderr, usage, argv[0], argv[0]);
+ return -1;
+ }
if (!homedir)
ERROR("$HOME not set");
- snprintf (FRONTEND_DEV, sizeof(FRONTEND_DEV),
- "/dev/dvb/adapter%i/frontend%i", adapter, frontend);
+ snprintf (FRONTEND_DEV, sizeof(FRONTEND_DEV),
+ "/dev/dvb/adapter%i/frontend%i", adapter, frontend);
- snprintf (DEMUX_DEV, sizeof(DEMUX_DEV),
- "/dev/dvb/adapter%i/demux%i", adapter, demux);
+ snprintf (DEMUX_DEV, sizeof(DEMUX_DEV),
+ "/dev/dvb/adapter%i/demux%i", adapter, demux);
printf ("using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV);
if (!confname)
{
+ int len = strlen(homedir) + strlen(CHANNEL_FILE) + 18;
if (!homedir)
ERROR("$HOME not set");
- confname = malloc(strlen(homedir) + strlen(CHANNEL_FILE) + 1);
- memcpy(confname, homedir, strlen(homedir));
- memcpy(confname + strlen(homedir), CHANNEL_FILE,
- strlen(CHANNEL_FILE) + 1);
+ confname = malloc(len);
+ snprintf(confname, len, "%s/.czap/%i/%s",
+ homedir, adapter, CHANNEL_FILE);
+ if (access(confname, R_OK))
+ snprintf(confname, len, "%s/.czap/%s",
+ homedir, CHANNEL_FILE);
}
+ printf("reading channels from file '%s'\n", confname);
+
memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters));
if (parse(confname, list_channels, chan_no, channel, &frontend_param, &vpid, &apid))
@@ -357,7 +381,7 @@ int main(int argc, char **argv)
if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0)
return -1;
- check_frontend (frontend_fd);
+ check_frontend (frontend_fd, human_readable);
close (audio_fd);
close (video_fd);
@@ -365,4 +389,3 @@ int main(int argc, char **argv)
return 0;
}
-
diff --git a/util/szap/femon.c b/util/szap/femon.c
deleted file mode 100644
index 47e37a3..0000000
--- a/util/szap/femon.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* femon -- monitor frontend status
- *
- * Copyright (C) 2003 convergence GmbH
- * Johannes Stezenbach <js@convergence.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#include <fcntl.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <stdint.h>
-#include <sys/time.h>
-
-#include <linux/dvb/frontend.h>
-
-#ifndef TRUE
-#define TRUE (1==1)
-#endif
-#ifndef FALSE
-#define FALSE (1==0)
-#endif
-
-
-#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d"
-
-static char *usage_str =
- "\nusage: femon [options]\n"
- " -a number : use given adapter (default 0)\n"
- " -f number : use given frontend (default 0)\n\n";
-
-
-static void usage(void)
-{
- fprintf(stderr, usage_str);
- exit(1);
-}
-
-
-static
-int check_frontend (int fe_fd)
-{
- fe_status_t status;
- uint16_t snr, signal;
- uint32_t ber, uncorrected_blocks;
-
- do {
- ioctl(fe_fd, FE_READ_STATUS, &status);
- ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal);
- ioctl(fe_fd, FE_READ_SNR, &snr);
- ioctl(fe_fd, FE_READ_BER, &ber);
- ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
-
- printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
- status, signal, snr, ber, uncorrected_blocks);
-
- if (status & FE_HAS_LOCK)
- printf("FE_HAS_LOCK");
-
- printf("\n");
- usleep(1000000);
- } while (1);
-
- return 0;
-}
-
-
-static
-int do_mon(unsigned int adapter, unsigned int frontend)
-{
- char fedev[128];
- int fefd;
- int result;
- struct dvb_frontend_info fe_info;
-
- snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend);
- printf("using '%s'\n", fedev);
-
- if ((fefd = open(fedev, O_RDONLY | O_NONBLOCK)) < 0) {
- perror("opening frontend failed");
- return FALSE;
- }
-
- result = ioctl(fefd, FE_GET_INFO, &fe_info);
-
- if (result < 0) {
- perror("ioctl FE_GET_INFO failed");
- close(fefd);
- return FALSE;
- }
-
- printf("FE: %s (%s)\n", fe_info.name, fe_info.type == FE_QPSK ? "SAT" :
- fe_info.type == FE_QAM ? "CABLE": "TERRESTRIAL");
-
- check_frontend (fefd);
-
- close(fefd);
-
- return result;
-}
-
-int main(int argc, char *argv[])
-{
- unsigned int adapter = 0, frontend = 0;
- int opt;
-
- while ((opt = getopt(argc, argv, "hlrn:a:f:d:")) != -1) {
- switch (opt)
- {
- case '?':
- case 'h':
- default:
- usage();
- case 'a':
- adapter = strtoul(optarg, NULL, 0);
- break;
- case 'f':
- frontend = strtoul(optarg, NULL, 0);
- }
- }
-
- do_mon(adapter, frontend);
-
- return FALSE;
-}
-
diff --git a/util/szap/lnb.c b/util/szap/lnb.c
new file mode 100644
index 0000000..9052d1c
--- /dev/null
+++ b/util/szap/lnb.c
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "lnb.h"
+
+static char *univ_desc[] = {
+ "Europe",
+ "10800 to 11800 MHz and 11600 to 12700 Mhz",
+ "Dual LO, loband 9750, hiband 10600 MHz",
+ (char *)NULL };
+
+static char *dbs_desc[] = {
+ "Expressvu, North America",
+ "12200 to 12700 MHz",
+ "Single LO, 11250 MHz",
+ (char *)NULL };
+
+static char *standard_desc[] = {
+ "10945 to 11450 Mhz",
+ "Single LO, 10000 Mhz",
+ (char *)NULL };
+
+static char *enhan_desc[] = {
+ "Astra",
+ "10700 to 11700 MHz",
+ "Single LO, 9750 MHz",
+ (char *)NULL };
+
+static char *cband_desc[] = {
+ "Big Dish",
+ "3700 to 4200 MHz",
+ "Single LO, 5150 Mhz",
+ (char *)NULL };
+
+static struct lnb_types_st lnbs[] = {
+ {"UNIVERSAL", univ_desc, 9750, 10600, 11700 },
+ {"DBS", dbs_desc, 11250, 0, 0 },
+ {"STANDARD", standard_desc, 10000, 0, 0 },
+ {"ENHANCED", enhan_desc, 9750, 0, 0 },
+ {"C-BAND", cband_desc, 5150, 0, 0 }
+};
+
+/* Enumerate through standard types of LNB's until NULL returned.
+ * Increment curno each time
+ */
+
+struct lnb_types_st *
+lnb_enum(int curno)
+{
+ if (curno >= (int) (sizeof(lnbs) / sizeof(lnbs[0])))
+ return (struct lnb_types_st *)NULL;
+ return &lnbs[curno];
+}
+
+/* Decode an lnb type, for example given on a command line
+ * If alpha and standard type, e.g. "Universal" then match that
+ * otherwise low[,high[,switch]]
+ */
+
+int
+lnb_decode(char *str, struct lnb_types_st *lnbp)
+{
+int i;
+char *cp, *np;
+
+ memset(lnbp, 0, sizeof(*lnbp));
+ cp = str;
+ while(*cp && isspace(*cp))
+ cp++;
+ if (isalpha(*cp)) {
+ for (i = 0; i < (int)(sizeof(lnbs) / sizeof(lnbs[0])); i++) {
+ if (!strcasecmp(lnbs[i].name, cp)) {
+ *lnbp = lnbs[i];
+ return 1;
+ }
+ }
+ return -1;
+ }
+ if (*cp == '\0' || !isdigit(*cp))
+ return -1;
+ lnbp->low_val = strtoul(cp, &np, 0);
+ if (lnbp->low_val == 0)
+ return -1;
+ cp = np;
+ while(*cp && (isspace(*cp) || *cp == ','))
+ cp++;
+ if (*cp == '\0')
+ return 1;
+ if (!isdigit(*cp))
+ return -1;
+ lnbp->high_val = strtoul(cp, &np, 0);
+ cp = np;
+ while(*cp && (isspace(*cp) || *cp == ','))
+ cp++;
+ if (*cp == '\0')
+ return 1;
+ if (!isdigit(*cp))
+ return -1;
+ lnbp->switch_val = strtoul(cp, NULL, 0);
+ return 1;
+}
diff --git a/util/szap/lnb.h b/util/szap/lnb.h
new file mode 100644
index 0000000..6370fd4
--- /dev/null
+++ b/util/szap/lnb.h
@@ -0,0 +1,22 @@
+struct lnb_types_st {
+ char *name;
+ char **desc;
+ unsigned long low_val;
+ unsigned long high_val; /* zero indicates no hiband */
+ unsigned long switch_val; /* zero indicates no hiband */
+};
+
+/* Enumerate through standard types of LNB's until NULL returned.
+ * Increment curno each time
+ */
+
+struct lnb_types_st *
+lnb_enum(int curno);
+
+/* Decode an lnb type, for example given on a command line
+ * If alpha and standard type, e.g. "Universal" then match that
+ * otherwise low[,high[,switch]]
+ */
+
+int
+lnb_decode(char *str, struct lnb_types_st *lnbp);
diff --git a/util/szap/szap.c b/util/szap/szap.c
index 581c970..ed1aa51 100644
--- a/util/szap/szap.c
+++ b/util/szap/szap.c
@@ -36,6 +36,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
+#include <sys/param.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
@@ -45,6 +46,7 @@
#include <linux/dvb/frontend.h>
#include <linux/dvb/dmx.h>
+#include <linux/dvb/audio.h>
#include "lnb.h"
#ifndef TRUE
@@ -64,6 +66,7 @@
#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d"
#define DEMUXDEVICE "/dev/dvb/adapter%d/demux%d"
+#define AUDIODEVICE "/dev/dvb/adapter%d/audio%d"
static struct lnb_types_st lnb_type;
@@ -79,18 +82,21 @@ static char *usage_str =
" -f number : use given frontend (default 0)\n"
" -d number : use given demux (default 0)\n"
" -c file : read channels list from 'file'\n"
+ " -b : enable Audio Bypass (default no)\n"
" -x : exit after tuning\n"
+ " -H : human readable output\n"
" -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n"
" -l lnb-type (DVB-S Only) (use -l help to print types) or \n"
" -l low[,high[,switch]] in Mhz\n"
" -i : run interactively, allowing you to type in channel names\n"
+ " -p : add pat and pmt to TS recording (implies -r)\n"
" or -n numbers for zapping\n";
-static int set_demux(int dmxfd, int pid, int audio, int dvr)
+static int set_demux(int dmxfd, int pid, int pes_type, int dvr)
{
struct dmx_pes_filter_params pesfilter;
- if (pid <= 0 || pid >= 0x1fff) /* ignore this pid to allow radio services */
+ if (pid < 0 || pid >= 0x1fff) /* ignore this pid to allow radio services */
return TRUE;
if (dvr) {
@@ -102,7 +108,7 @@ static int set_demux(int dmxfd, int pid, int audio, int dvr)
pesfilter.pid = pid;
pesfilter.input = DMX_IN_FRONTEND;
pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER;
- pesfilter.pes_type = audio ? DMX_PES_AUDIO : DMX_PES_VIDEO;
+ pesfilter.pes_type = pes_type;
pesfilter.flags = DMX_IMMEDIATE_START;
if (ioctl(dmxfd, DMX_SET_PES_FILTER, &pesfilter) == -1) {
@@ -114,6 +120,65 @@ static int set_demux(int dmxfd, int pid, int audio, int dvr)
return TRUE;
}
+int get_pmt_pid(char *dmxdev, int sid)
+{
+ int patfd, count;
+ int pmt_pid = 0;
+ int patread = 0;
+ int section_length;
+ unsigned char buft[4096];
+ unsigned char *buf = buft;
+ struct dmx_sct_filter_params f;
+
+ memset(&f, 0, sizeof(f));
+ f.pid = 0;
+ f.filter.filter[0] = 0x00;
+ f.filter.mask[0] = 0xff;
+ f.timeout = 0;
+ f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC;
+
+ if ((patfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("openening pat demux failed");
+ return -1;
+ }
+
+ if (ioctl(patfd, DMX_SET_FILTER, &f) == -1) {
+ perror("ioctl DMX_SET_FILTER failed");
+ close(patfd);
+ return -1;
+ }
+
+ while (!patread){
+ if (((count = read(patfd, buf, sizeof(buft))) < 0) && errno == EOVERFLOW)
+ count = read(patfd, buf, sizeof(buft));
+ if (count < 0) {
+ perror("read_sections: read error");
+ close(patfd);
+ return -1;
+ }
+
+ section_length = ((buf[1] & 0x0f) << 8) | buf[2];
+ if (count != section_length + 3)
+ continue;
+
+ buf += 8;
+ section_length -= 8;
+
+ patread = 1; /* assumes one section contains the whole pat */
+ while (section_length > 0) {
+ int service_id = (buf[0] << 8) | buf[1];
+ if (service_id == sid) {
+ pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3];
+ section_length = 0;
+ }
+ buf += 4;
+ section_length -= 4;
+ }
+ }
+
+ close(patfd);
+ return pmt_pid;
+}
struct diseqc_cmd {
struct dvb_diseqc_master_cmd cmd;
@@ -151,14 +216,14 @@ static int diseqc(int secfd, int sat_no, int pol_vert, int hi_band)
{ {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
/* param: high nibble: reset bits, low nibble set bits,
- * bits are: option, position, polarizaion, band
+ * bits are: option, position, polarization, band
*/
cmd.cmd.msg[3] =
0xf0 | (((sat_no * 4) & 0x0f) | (hi_band ? 1 : 0) | (pol_vert ? 0 : 2));
diseqc_send_msg(secfd, pol_vert ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18,
&cmd, hi_band ? SEC_TONE_ON : SEC_TONE_OFF,
- (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
+ sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
return TRUE;
}
@@ -189,8 +254,9 @@ static int do_tune(int fefd, unsigned int ifreq, unsigned int sr)
static
-int check_frontend (int fe_fd, int dvr)
+int check_frontend (int fe_fd, int dvr, int human_readable)
{
+ (void)dvr;
fe_status_t status;
uint16_t snr, signal;
uint32_t ber, uncorrected_blocks;
@@ -210,8 +276,13 @@ int check_frontend (int fe_fd, int dvr)
if (ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1)
uncorrected_blocks = -2;
- printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
- status, signal, snr, ber, uncorrected_blocks);
+ if (human_readable) {
+ printf ("status %02x | signal %3u%% | snr %3u%% | ber %d | unc %d | ",
+ status, (signal * 100) / 0xffff, (snr * 100) / 0xffff, ber, uncorrected_blocks);
+ } else {
+ printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
+ status, signal, snr, ber, uncorrected_blocks);
+ }
if (status & FE_HAS_LOCK)
printf("FE_HAS_LOCK");
@@ -230,10 +301,12 @@ int check_frontend (int fe_fd, int dvr)
static
int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
unsigned int sat_no, unsigned int freq, unsigned int pol,
- unsigned int sr, unsigned int vpid, unsigned int apid, int dvr)
+ unsigned int sr, unsigned int vpid, unsigned int apid, int sid,
+ int dvr, int rec_psi, int bypass, int human_readable)
{
- char fedev[128], dmxdev[128];
- static int fefd, videofd, audiofd;
+ char fedev[128], dmxdev[128], auddev[128];
+ static int fefd, dmxfda, dmxfdv, audiofd = -1, patfd, pmtfd;
+ int pmtpid;
uint32_t ifreq;
int hiband, result;
static struct dvb_frontend_info fe_info;
@@ -241,6 +314,7 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
if (!fefd) {
snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend);
snprintf(dmxdev, sizeof(dmxdev), DEMUXDEVICE, adapter, demux);
+ snprintf(auddev, sizeof(auddev), AUDIODEVICE, adapter, demux);
printf("using '%s' and '%s'\n", fedev, dmxdev);
if ((fefd = open(fedev, O_RDWR | O_NONBLOCK)) < 0) {
@@ -262,18 +336,41 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
return FALSE;
}
- if ((videofd = open(dmxdev, O_RDWR)) < 0) {
+ if ((dmxfdv = open(dmxdev, O_RDWR)) < 0) {
perror("opening video demux failed");
close(fefd);
return FALSE;
}
- if ((audiofd = open(dmxdev, O_RDWR)) < 0) {
+ if ((dmxfda = open(dmxdev, O_RDWR)) < 0) {
perror("opening audio demux failed");
- close(videofd);
close(fefd);
return FALSE;
}
+
+ if (dvr == 0) /* DMX_OUT_DECODER */
+ audiofd = open(auddev, O_RDWR);
+
+ if (rec_psi){
+ if ((patfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening pat demux failed");
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((pmtfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening pmt demux failed");
+ close(patfd);
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ return FALSE;
+ }
+ }
}
hiband = 0;
@@ -293,15 +390,36 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
if (diseqc(fefd, sat_no, pol, hiband))
if (do_tune(fefd, ifreq, sr))
- if (set_demux(videofd, vpid, 0, dvr))
- if (set_demux(audiofd, apid, 1, dvr))
- result = TRUE;
-
- check_frontend (fefd, dvr);
+ if (set_demux(dmxfdv, vpid, DMX_PES_VIDEO, dvr))
+ if (audiofd >= 0)
+ (void)ioctl(audiofd, AUDIO_SET_BYPASS_MODE, bypass);
+ if (set_demux(dmxfda, apid, DMX_PES_AUDIO, dvr)) {
+ if (rec_psi) {
+ pmtpid = get_pmt_pid(dmxdev, sid);
+ if (pmtpid < 0) {
+ result = FALSE;
+ }
+ if (pmtpid == 0) {
+ fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid);
+ result = FALSE;
+ }
+ if (set_demux(patfd, 0, DMX_PES_OTHER, dvr))
+ if (set_demux(pmtfd, pmtpid, DMX_PES_OTHER, dvr))
+ result = TRUE;
+ } else {
+ result = TRUE;
+ }
+ }
+
+ check_frontend (fefd, dvr, human_readable);
if (!interactive) {
- close(audiofd);
- close(videofd);
+ close(patfd);
+ close(pmtfd);
+ if (audiofd >= 0)
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
close(fefd);
}
@@ -312,14 +430,15 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
static int read_channels(const char *filename, int list_channels,
uint32_t chan_no, const char *chan_name,
unsigned int adapter, unsigned int frontend,
- unsigned int demux, int dvr)
+ unsigned int demux, int dvr, int rec_psi,
+ int bypass, int human_readable)
{
FILE *cfp;
char buf[4096];
char inp[256];
char *field, *tmp, *p;
unsigned int line;
- unsigned int freq, pol, sat_no, sr, vpid, apid;
+ unsigned int freq, pol, sat_no, sr, vpid, apid, sid;
int ret;
again:
@@ -399,20 +518,41 @@ again:
goto syntax_err;
vpid = strtoul(field, NULL, 0);
+ if (!vpid)
+ vpid = 0x1fff;
if (!(field = strsep(&tmp, ":")))
goto syntax_err;
+ p = strchr(field, ';');
+
+ if (p) {
+ *p = '\0';
+ p++;
+ if (bypass) {
+ if (!p || !*p)
+ goto syntax_err;
+ field = p;
+ }
+ }
+
apid = strtoul(field, NULL, 0);
+ if (!apid)
+ apid = 0x1fff;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sid = strtoul(field, NULL, 0);
printf("sat %u, frequency = %u MHz %c, symbolrate %u, "
- "vpid = 0x%04x, apid = 0x%04x\n",
- sat_no, freq, pol ? 'V' : 'H', sr, vpid, apid);
+ "vpid = 0x%04x, apid = 0x%04x sid = 0x%04x\n",
+ sat_no, freq, pol ? 'V' : 'H', sr, vpid, apid, sid);
fclose(cfp);
- ret = zap_to(adapter, frontend, demux,
- sat_no, freq * 1000, pol, sr, vpid, apid, dvr);
+ ret = zap_to(adapter, frontend, demux, sat_no, freq * 1000,
+ pol, sr, vpid, apid, sid, dvr, rec_psi, bypass, human_readable);
if (interactive)
goto again;
@@ -475,17 +615,22 @@ int main(int argc, char *argv[])
int list_channels = 0;
unsigned int chan_no = 0;
const char *chan_name = NULL;
- unsigned int adapter = 0, frontend = 0, demux = 0, dvr = 0;
+ unsigned int adapter = 0, frontend = 0, demux = 0, dvr = 0, rec_psi = 0;
+ int bypass = 0;
int opt, copt = 0;
+ int human_readable = 0;
lnb_type = *lnb_enum(0);
- while ((opt = getopt(argc, argv, "hqrn:a:f:d:c:l:xi")) != -1) {
+ while ((opt = getopt(argc, argv, "Hhqrpn:a:f:d:c:l:xib")) != -1) {
switch (opt)
{
case '?':
case 'h':
default:
bad_usage(argv[0], 0);
+ case 'b':
+ bypass = 1;
+ break;
case 'q':
list_channels = 1;
break;
@@ -501,6 +646,9 @@ int main(int argc, char *argv[])
case 'f':
frontend = strtoul(optarg, NULL, 0);
break;
+ case 'p':
+ rec_psi = 1;
+ break;
case 'd':
demux = strtoul(optarg, NULL, 0);
break;
@@ -517,6 +665,9 @@ int main(int argc, char *argv[])
case 'x':
exit_after_tuning = 1;
break;
+ case 'H':
+ human_readable = 1;
+ break;
case 'i':
interactive = 1;
exit_after_tuning = 1;
@@ -545,16 +696,21 @@ int main(int argc, char *argv[])
fprintf(stderr, "error: $HOME not set\n");
return TRUE;
}
- strncpy(chanfile, home, sizeof(chanfile));
- strcat(chanfile, "/.szap/" CHANNEL_FILE);
+ snprintf(chanfile, sizeof(chanfile),
+ "%s/.szap/%i/%s", home, adapter, CHANNEL_FILE);
+ if (access(chanfile, R_OK))
+ snprintf(chanfile, sizeof(chanfile),
+ "%s/.szap/%s", home, CHANNEL_FILE);
}
printf("reading channels from file '%s'\n", chanfile);
+ if (rec_psi)
+ dvr=1;
+
if (!read_channels(chanfile, list_channels, chan_no, chan_name,
- adapter, frontend, demux, dvr))
+ adapter, frontend, demux, dvr, rec_psi, bypass, human_readable))
return TRUE;
return FALSE;
}
-
diff --git a/util/szap/tzap.c b/util/szap/tzap.c
index 2527c23..cd87bfa 100644
--- a/util/szap/tzap.c
+++ b/util/szap/tzap.c
@@ -1,3 +1,24 @@
+/* tzap -- DVB-T zapping utility
+ */
+
+/*
+ * Added recording to a file
+ * arguments:
+ *
+ * -t timeout (seconds)
+ * -o filename output filename (use -o - for stdout)
+ * -s only print summary
+ * -S run silently (no output)
+ *
+ * Bernard Hatt 24/2/04
+ */
+
+
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+#define _LARGEFILE64_SOURCE 1
+
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
@@ -9,15 +30,19 @@
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
+#include <signal.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/dmx.h>
-
static char FRONTEND_DEV [80];
static char DEMUX_DEV [80];
+static char DVR_DEV [80];
+static int timeout_flag=0;
+static int silent=0,timeout=0;
+static int exit_after_tuning;
-#define CHANNEL_FILE "/.tzap/channels.conf"
+#define CHANNEL_FILE "channels.conf"
#define ERROR(x...) \
do { \
@@ -68,14 +93,16 @@ static const Param guard_list [] = {
{"GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16},
{"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32},
{"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4},
- {"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8}
+ {"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8},
+ {"GUARD_INTERVAL_AUTO", GUARD_INTERVAL_AUTO}
};
static const Param hierarchy_list [] = {
{ "HIERARCHY_1", HIERARCHY_1 },
{ "HIERARCHY_2", HIERARCHY_2 },
{ "HIERARCHY_4", HIERARCHY_4 },
- { "HIERARCHY_NONE", HIERARCHY_NONE }
+ { "HIERARCHY_NONE", HIERARCHY_NONE },
+ { "HIERARCHY_AUTO", HIERARCHY_AUTO }
};
static const Param constellation_list [] = {
@@ -84,12 +111,14 @@ static const Param constellation_list [] = {
{ "QAM_16", QAM_16 },
{ "QAM_256", QAM_256 },
{ "QAM_32", QAM_32 },
- { "QAM_64", QAM_64 }
+ { "QAM_64", QAM_64 },
+ { "QAM_AUTO", QAM_AUTO }
};
static const Param transmissionmode_list [] = {
{ "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K },
{ "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K },
+ { "TRANSMISSION_MODE_AUTO", TRANSMISSION_MODE_AUTO }
};
#define LIST_SIZE(x) sizeof(x)/sizeof(Param)
@@ -100,7 +129,7 @@ int parse_param (int fd, const Param * plist, int list_size, int *param)
{
char c;
int character = 0;
- int index = 0;
+ int _index = 0;
while (1) {
if (read(fd, &c, 1) < 1)
@@ -111,9 +140,9 @@ int parse_param (int fd, const Param * plist, int list_size, int *param)
break;
while (toupper(c) != plist->name[character]) {
- index++;
+ _index++;
plist++;
- if (index >= list_size) /* parse error, no valid */
+ if (_index >= list_size) /* parse error, no valid */
return -2; /* parameter name found */
}
@@ -150,7 +179,10 @@ int parse_int(int fd, int *val)
return -3; /* to fit in 32 bit */
};
+ errno = 0;
*val = strtol(number, NULL, 10);
+ if (errno == ERANGE)
+ return -4;
return 0;
}
@@ -167,13 +199,18 @@ int find_channel(int fd, const char *channel)
if (read(fd, &c, 1) < 1)
return -1; /* EOF! */
- if (c == ':' && channel[character] == '\0')
- break;
-
- if (toupper(c) == toupper(channel[character]))
- character++;
- else
+ if ( '\n' == c ) /* start of line */
character = 0;
+ else if ( character >= 0 ) { /* we are in the namefield */
+
+ if (c == ':' && channel[character] == '\0')
+ break;
+
+ if (toupper(c) == toupper(channel[character]))
+ character++;
+ else
+ character = -1;
+ }
};
return 0;
@@ -211,12 +248,32 @@ int try_parse_param(int fd, const Param * plist, int list_size, int *param,
return err;
}
+static int check_fec(fe_code_rate_t *fec)
+{
+ switch (*fec)
+ {
+ case FEC_NONE:
+ *fec = FEC_AUTO;
+ case FEC_AUTO:
+ case FEC_1_2:
+ case FEC_2_3:
+ case FEC_3_4:
+ case FEC_5_6:
+ case FEC_7_8:
+ return 0;
+ default:
+ ;
+ }
+ return 1;
+}
+
int parse(const char *fname, const char *channel,
struct dvb_frontend_parameters *frontend, int *vpid, int *apid)
{
int fd;
int err;
+ int tmp;
if ((fd = open(fname, O_RDONLY | O_NONBLOCK)) < 0) {
PERROR ("could not open file '%s'", fname);
@@ -229,54 +286,57 @@ int parse(const char *fname, const char *channel,
return -2;
}
- if ((err = try_parse_int(fd, &frontend->frequency, "frequency")))
+ if ((err = try_parse_int(fd, &tmp, "frequency")))
return -3;
+ frontend->frequency = tmp;
if ((err = try_parse_param(fd,
inversion_list, LIST_SIZE(inversion_list),
- (int *) &frontend->inversion,
- "inversion")))
+ &tmp, "inversion")))
return -4;
+ frontend->inversion = tmp;
if ((err = try_parse_param(fd, bw_list, LIST_SIZE(bw_list),
- (int *) &frontend->u.ofdm.bandwidth,
- "bandwidth")))
+ &tmp, "bandwidth")))
return -5;
+ frontend->u.ofdm.bandwidth = tmp;
if ((err = try_parse_param(fd, fec_list, LIST_SIZE(fec_list),
- (int *) &frontend->u.ofdm.code_rate_HP,
- "code_rate_HP")))
+ &tmp, "code_rate_HP")))
+ return -6;
+ frontend->u.ofdm.code_rate_HP = tmp;
+ if (check_fec(&frontend->u.ofdm.code_rate_HP))
return -6;
if ((err = try_parse_param(fd, fec_list, LIST_SIZE(fec_list),
- (int *) &frontend->u.ofdm.code_rate_LP,
- "code_rate_LP")))
+ &tmp, "code_rate_LP")))
+ return -7;
+ frontend->u.ofdm.code_rate_LP = tmp;
+ if (check_fec(&frontend->u.ofdm.code_rate_LP))
return -7;
if ((err = try_parse_param(fd, constellation_list,
LIST_SIZE(constellation_list),
- (int *) &frontend->u.ofdm.constellation,
- "constellation")))
+ &tmp, "constellation")))
return -8;
+ frontend->u.ofdm.constellation = tmp;
if ((err = try_parse_param(fd, transmissionmode_list,
LIST_SIZE(transmissionmode_list),
- (int *) &frontend->u.ofdm.
- transmission_mode,
- "transmission_mode")))
+ &tmp, "transmission_mode")))
return -9;
+ frontend->u.ofdm.transmission_mode = tmp;
if ((err = try_parse_param(fd, guard_list, LIST_SIZE(guard_list),
- (int *) &frontend->u.ofdm.
- guard_interval, "guard_interval")))
+ &tmp, "guard_interval")))
return -10;
+ frontend->u.ofdm.guard_interval = tmp;
if ((err = try_parse_param(fd, hierarchy_list,
LIST_SIZE(hierarchy_list),
- (int *) &frontend->u.ofdm.
- hierarchy_information,
- "hierarchy_information")))
+ &tmp, "hierarchy_information")))
return -11;
+ frontend->u.ofdm.hierarchy_information = tmp;
if ((err = try_parse_int(fd, vpid, "Video PID")))
return -12;
@@ -330,7 +390,8 @@ int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend)
return -1;
}
- printf ("tuning to %i Hz\n", frontend->frequency);
+ if (silent<2)
+ fprintf (stderr,"tuning to %i Hz\n", frontend->frequency);
if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) {
PERROR("ioctl FE_SET_FRONTEND failed");
@@ -340,38 +401,115 @@ int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend)
return 0;
}
+static void
+do_timeout(int x)
+{
+ (void)x;
+ if (timeout_flag==0)
+ {
+ timeout_flag=1;
+ alarm(2);
+ signal(SIGALRM, do_timeout);
+ }
+ else
+ {
+ /* something has gone wrong ... exit */
+ exit(1);
+ }
+}
-static
-int check_frontend (int fe_fd)
+static void
+print_frontend_stats (int fe_fd, int human_readable)
{
fe_status_t status;
- uint16_t snr, signal;
+ uint16_t snr, _signal;
uint32_t ber, uncorrected_blocks;
- do {
- ioctl(fe_fd, FE_READ_STATUS, &status);
- ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal);
- ioctl(fe_fd, FE_READ_SNR, &snr);
- ioctl(fe_fd, FE_READ_BER, &ber);
- ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
+ ioctl(fe_fd, FE_READ_STATUS, &status);
+ ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &_signal);
+ ioctl(fe_fd, FE_READ_SNR, &snr);
+ ioctl(fe_fd, FE_READ_BER, &ber);
+ ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
+
+ if (human_readable) {
+ printf ("status %02x | signal %3u%% | snr %3u%% | ber %d | unc %d | ",
+ status, (_signal * 100) / 0xffff, (snr * 100) / 0xffff, ber, uncorrected_blocks);
+ } else {
+ fprintf (stderr, "status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
+ status, _signal, snr, ber, uncorrected_blocks);
+ }
- printf ("status %02x | signal %04x | snr %04x | "
- "ber %08x | unc %08x | ",
- status, signal, snr, ber, uncorrected_blocks);
+ if (status & FE_HAS_LOCK)
+ fprintf(stderr,"FE_HAS_LOCK");
- if (status & FE_HAS_LOCK)
- printf("FE_HAS_LOCK");
+ fprintf(stderr,"\n");
+}
+static
+int check_frontend (int fe_fd, int human_readable)
+{
+ fe_status_t status;
+ do {
+ ioctl(fe_fd, FE_READ_STATUS, &status);
+ if (!silent)
+ print_frontend_stats(fe_fd, human_readable);
+ if (exit_after_tuning && (status & FE_HAS_LOCK))
+ break;
usleep(1000000);
-
- printf("\n");
- } while (1);
+ } while (!timeout_flag);
+ if (silent < 2)
+ print_frontend_stats (fe_fd, human_readable);
return 0;
}
+#define BUFLEN (188*256)
+static
+void copy_to_file(int in_fd, int out_fd)
+{
+ char buf[BUFLEN];
+ int r;
+ long long int rc = 0LL;
+ while(timeout_flag==0)
+ {
+ r=read(in_fd,buf,BUFLEN);
+ if (r < 0) {
+ if (errno == EOVERFLOW) {
+ printf("buffer overrun\n");
+ continue;
+ }
+ PERROR("Read failed");
+ break;
+ }
+ if (write(out_fd,buf,r) < 0) {
+ PERROR("Write failed");
+ break;
+ }
+ rc+=r;
+ }
+ if (silent<2)
+ {
+ fprintf(stderr, "copied %lld bytes (%lld Kbytes/sec)\n",rc,rc/(1024*timeout));
+ }
+}
-static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] [-r] <channel name>\n\n";
+static char *usage =
+ "usage:\n"
+ " tzap [options] <channel_name>\n"
+ " zap to channel channel_name (case insensitive)\n"
+ " -a number : use given adapter (default 0)\n"
+ " -f number : use given frontend (default 0)\n"
+ " -d number : use given demux (default 0)\n"
+ " -c file : read channels list from 'file'\n"
+ " -x : exit after tuning\n"
+ " -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n"
+ " -s : only print summary\n"
+ " -S : run silently (no output)\n"
+ " -H : human readable output\n"
+ " -F : set up frontend only, don't touch demux\n"
+ " -t number : timeout (seconds)\n"
+ " -o file : output filename (use -o - for stdout)\n"
+ " -h -? : display this help and exit\n";
int main(int argc, char **argv)
@@ -382,10 +520,14 @@ int main(int argc, char **argv)
char *channel = NULL;
int adapter = 0, frontend = 0, demux = 0, dvr = 0;
int vpid, apid;
- int frontend_fd, audio_fd, video_fd;
+ int frontend_fd, audio_fd = 0, video_fd = 0, dvr_fd, file_fd;
int opt;
+ int record = 0;
+ int frontend_only = 0;
+ char *filename = NULL;
+ int human_readable = 0;
- while ((opt = getopt(argc, argv, "hrn:a:f:d:c:")) != -1) {
+ while ((opt = getopt(argc, argv, "H?hrxRsFSn:a:f:d:c:t:o:")) != -1) {
switch (opt) {
case 'a':
adapter = strtoul(optarg, NULL, 0);
@@ -396,12 +538,34 @@ int main(int argc, char **argv)
case 'd':
demux = strtoul(optarg, NULL, 0);
break;
+ case 't':
+ timeout = strtoul(optarg, NULL, 0);
+ break;
+ case 'o':
+ filename = strdup(optarg);
+ record=1;
+ /* fall through */
case 'r':
dvr = 1;
break;
+ case 'x':
+ exit_after_tuning = 1;
+ break;
case 'c':
confname = optarg;
break;
+ case 's':
+ silent = 1;
+ break;
+ case 'S':
+ silent = 2;
+ break;
+ case 'F':
+ frontend_only = 1;
+ break;
+ case 'H':
+ human_readable = 1;
+ break;
case '?':
case 'h':
default:
@@ -424,17 +588,25 @@ int main(int argc, char **argv)
snprintf (DEMUX_DEV, sizeof(DEMUX_DEV),
"/dev/dvb/adapter%i/demux%i", adapter, demux);
- printf ("using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV);
+ snprintf (DVR_DEV, sizeof(DVR_DEV),
+ "/dev/dvb/adapter%i/dvr%i", adapter, demux);
+
+ if (silent<2)
+ fprintf (stderr,"using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV);
if (!confname)
{
+ int len = strlen(homedir) + strlen(CHANNEL_FILE) + 18;
if (!homedir)
ERROR ("$HOME not set");
- confname = malloc (strlen(homedir) + strlen(CHANNEL_FILE) + 1);
- memcpy (confname, homedir, strlen(homedir));
- memcpy (confname + strlen(homedir), CHANNEL_FILE,
- strlen(CHANNEL_FILE) + 1);
+ confname = malloc (len);
+ snprintf (confname, len, "%s/.tzap/%i/%s",
+ homedir, adapter, CHANNEL_FILE);
+ if (access (confname, R_OK))
+ snprintf (confname, len, "%s/.tzap/%s",
+ homedir, CHANNEL_FILE);
}
+ printf("reading channels from file '%s'\n", confname);
memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters));
@@ -449,12 +621,17 @@ int main(int argc, char **argv)
if (setup_frontend (frontend_fd, &frontend_param) < 0)
return -1;
+ if (frontend_only)
+ goto just_the_frontend_dude;
+
if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) {
PERROR("failed opening '%s'", DEMUX_DEV);
return -1;
}
- printf ("video pid 0x%04x, audio pid 0x%04x\n", vpid, apid);
+ if (silent<2)
+ fprintf (stderr,"video pid 0x%04x, audio pid 0x%04x\n", vpid, apid);
+
if (set_pesfilter (video_fd, vpid, DMX_PES_VIDEO, dvr) < 0)
return -1;
@@ -466,7 +643,51 @@ int main(int argc, char **argv)
if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0)
return -1;
- check_frontend (frontend_fd);
+ signal(SIGALRM,do_timeout);
+ if (timeout>0)
+ alarm(timeout);
+
+
+ if (record)
+ {
+ if (filename!=NULL)
+ {
+ if (strcmp(filename,"-")!=0)
+ {
+ file_fd = open (filename,O_WRONLY|O_LARGEFILE|O_CREAT,0644);
+ if (file_fd<0)
+ {
+ PERROR("open of '%s' failed",filename);
+ return -1;
+ }
+ }
+ else
+ {
+ file_fd=1;
+ }
+ }
+ else
+ {
+ PERROR("Record mode but no filename!");
+ return -1;
+ }
+
+ if ((dvr_fd = open(DVR_DEV, O_RDONLY)) < 0) {
+ PERROR("failed opening '%s'", DVR_DEV);
+ return -1;
+ }
+ if (silent<2)
+ print_frontend_stats (frontend_fd, human_readable);
+
+ copy_to_file(dvr_fd,file_fd);
+
+ if (silent<2)
+ print_frontend_stats (frontend_fd, human_readable);
+ }
+ else {
+just_the_frontend_dude:
+ check_frontend (frontend_fd, human_readable);
+ }
close (audio_fd);
close (video_fd);
@@ -474,4 +695,3 @@ int main(int argc, char **argv)
return 0;
}
-
diff --git a/util/ttusb_dec_reset/Makefile b/util/ttusb_dec_reset/Makefile
index cde7de5..b2ca852 100644
--- a/util/ttusb_dec_reset/Makefile
+++ b/util/ttusb_dec_reset/Makefile
@@ -1,17 +1,19 @@
-CC = gcc
-RM = rm -f
-CFLAGS = -g -Wall -O2
-LFLAGS = -g -Wall
-LDFLAGS = -lusb
+# Makefile for linuxtv.org dvb-apps/util/ttusb_dec_reset
-OBJS = ttusb_dec_reset.o
-TARGET = ttusb_dec_reset
+binaries = ttusb_dec_reset
-$(TARGET): $(OBJS)
- $(CC) $(LFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJS)
+ifneq ($(realpath $(binaries)),)
+inst_bin = $(binaries)
+endif
-.c.o:
- $(CC) $(CFLAGS) -c $< -o $@
+LDLIBS += -lusb
-clean:
- $(RM) *.o $(TARGET)
+.PHONY: all
+
+ifeq ($(ttusb_dec_reset),1)
+all: $(binaries)
+else
+all: clean
+endif
+
+include ../../Make.rules
diff --git a/util/ttusb_dec_reset/ttusb_dec_reset.c b/util/ttusb_dec_reset/ttusb_dec_reset.c
index 51ddfc7..54b3f83 100644
--- a/util/ttusb_dec_reset/ttusb_dec_reset.c
+++ b/util/ttusb_dec_reset/ttusb_dec_reset.c
@@ -25,10 +25,12 @@ void dec_reset(struct usb_device *dev)
}
}
-int main()
+int main(int argc, char *argv[])
{
struct usb_bus *busses;
struct usb_bus *bus;
+ (void) argc;
+ (void) argv;
usb_init();
usb_find_busses();
diff --git a/util/zap/Makefile b/util/zap/Makefile
new file mode 100644
index 0000000..35e0c6d
--- /dev/null
+++ b/util/zap/Makefile
@@ -0,0 +1,20 @@
+# Makefile for linuxtv.org dvb-apps/util/zap
+
+objects = zap_ca.o \
+ zap_dvb.o
+
+binaries = zap
+
+inst_bin = $(binaries)
+
+CPPFLAGS += -I../../lib
+LDFLAGS += -L../../lib/libdvbapi -L../../lib/libdvbsec -L../../lib/libdvbcfg -L../../lib/libdvben50221 -L../../lib/libucsi
+LDLIBS += -ldvbcfg -ldvben50221 -ldvbsec -ldvbapi -lucsi -lpthread
+
+.PHONY: all
+
+all: $(binaries)
+
+$(binaries): $(objects)
+
+include ../../Make.rules
diff --git a/util/zap/zap.c b/util/zap/zap.c
new file mode 100644
index 0000000..6f3df33
--- /dev/null
+++ b/util/zap/zap.c
@@ -0,0 +1,226 @@
+/*
+ ZAP utility
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/poll.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libdvbapi/dvbaudio.h>
+#include <libdvbsec/dvbsec_cfg.h>
+#include <libucsi/mpeg/section.h>
+#include "zap_dvb.h"
+#include "zap_ca.h"
+
+
+static void signal_handler(int _signal);
+
+static int quit_app = 0;
+
+void usage(void)
+{
+ static const char *_usage = "\n"
+ " ZAP: A zapping application\n"
+ " Copyright (C) 2004, 2005, 2006 Manu Abraham (manu@kromtek.com)\n"
+ " Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)\n\n"
+ " usage: zap <options> as follows:\n"
+ " -h help\n"
+ " -adapter <id> adapter to use (default 0)\n"
+ " -frontend <id> frontend to use (default 0)\n"
+ " -demux <id> demux to use (default 0)\n"
+ " -caslotnum <id> ca slot number to use (default 0)\n"
+ " -channels <filename> channels.conf file.\n"
+ " -secfile <filename> Optional sec.conf file.\n"
+ " -secid <secid> ID of the SEC configuration to use, one of:\n"
+ " -nomoveca Do not attempt to move CA descriptors from stream to programme level\n"
+ " <channel name>\n";
+ fprintf(stderr, "%s\n", _usage);
+
+ exit(1);
+}
+
+int find_channel(struct dvbcfg_zapchannel *channel, void *private_data)
+{
+ struct dvbcfg_zapchannel *tmpchannel = private_data;
+
+ if (strcmp(channel->name, tmpchannel->name) == 0) {
+ memcpy(tmpchannel, channel, sizeof(struct dvbcfg_zapchannel));
+ return 1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int adapter_id = 0;
+ int frontend_id = 0;
+ int demux_id = 0;
+ int caslot_num = 0;
+ char *chanfile = "/etc/channels.conf";
+ char *secfile = NULL;
+ char *secid = NULL;
+ char *channel_name = NULL;
+ int moveca = 1;
+ int argpos = 1;
+ struct zap_dvb_params zap_dvb_params;
+ struct zap_ca_params zap_ca_params;
+
+ while(argpos != argc) {
+ if (!strcmp(argv[argpos], "-h")) {
+ usage();
+ } else if (!strcmp(argv[argpos], "-adapter")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &adapter_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-frontend")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &frontend_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-demux")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &demux_id) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-caslotnum")) {
+ if ((argc - argpos) < 2)
+ usage();
+ if (sscanf(argv[argpos+1], "%i", &caslot_num) != 1)
+ usage();
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-channels")) {
+ if ((argc - argpos) < 2)
+ usage();
+ chanfile = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-secfile")) {
+ if ((argc - argpos) < 2)
+ usage();
+ secfile = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-secid")) {
+ if ((argc - argpos) < 2)
+ usage();
+ secid = argv[argpos+1];
+ argpos+=2;
+ } else if (!strcmp(argv[argpos], "-nomoveca")) {
+ moveca = 0;
+ argpos++;
+ } else {
+ if ((argc - argpos) != 1)
+ usage();
+ channel_name = argv[argpos];
+ argpos++;
+ }
+ }
+
+ // the user didn't select anything!
+ if (channel_name == NULL)
+ usage();
+
+ // setup any signals
+ signal(SIGINT, signal_handler);
+ signal(SIGPIPE, SIG_IGN);
+
+ // start the CA stuff
+ zap_ca_params.adapter_id = adapter_id;
+ zap_ca_params.caslot_num = caslot_num;
+ zap_ca_params.moveca = moveca;
+ zap_ca_start(&zap_ca_params);
+
+ // find the requested channel
+ if (strlen(channel_name) >= sizeof(zap_dvb_params.channel.name)) {
+ fprintf(stderr, "Channel name is too long %s\n", channel_name);
+ exit(1);
+ }
+ FILE *channel_file = fopen(chanfile, "r");
+ if (channel_file == NULL) {
+ fprintf(stderr, "Could open channel file %s\n", chanfile);
+ exit(1);
+ }
+ memcpy(zap_dvb_params.channel.name, channel_name, strlen(channel_name) + 1);
+ if (dvbcfg_zapchannel_parse(channel_file, find_channel, &zap_dvb_params.channel) != 1) {
+ fprintf(stderr, "Unable to find requested channel %s\n", channel_name);
+ exit(1);
+ }
+ fclose(channel_file);
+
+ // default SEC with a DVBS card
+ if ((secid == NULL) && (zap_dvb_params.channel.fe_type == DVBFE_TYPE_DVBS))
+ secid = "UNIVERSAL";
+
+ // look it up if one were supplied
+ zap_dvb_params.valid_sec = 0;
+ if (secid != NULL) {
+ if (dvbsec_cfg_find(secfile, secid,
+ &zap_dvb_params.sec)) {
+ fprintf(stderr, "Unable to find suitable sec/lnb configuration for channel\n");
+ exit(1);
+ }
+ zap_dvb_params.valid_sec = 1;
+ }
+
+ // open the frontend
+ zap_dvb_params.fe = dvbfe_open(adapter_id, frontend_id, 0);
+ if (zap_dvb_params.fe == NULL) {
+ fprintf(stderr, "Failed to open frontend\n");
+ exit(1);
+ }
+
+ // start the DVB stuff
+ zap_dvb_params.adapter_id = adapter_id;
+ zap_dvb_params.frontend_id = frontend_id;
+ zap_dvb_params.demux_id = demux_id;
+ zap_dvb_start(&zap_dvb_params);
+
+ // the UI
+ while(!quit_app) {
+ sleep(1);
+ }
+
+ // shutdown DVB stuff
+ if (channel_name != NULL)
+ zap_dvb_stop();
+
+ // shutdown CA stuff
+ zap_ca_stop();
+
+ // done
+ exit(0);
+}
+
+static void signal_handler(int _signal)
+{
+ (void) _signal;
+
+ if (!quit_app) {
+ quit_app = 1;
+ }
+}
diff --git a/util/zap/zap_ca.c b/util/zap/zap_ca.c
new file mode 100644
index 0000000..b78fdcf
--- /dev/null
+++ b/util/zap/zap_ca.c
@@ -0,0 +1,198 @@
+/*
+ ZAP utility CA functions
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <pthread.h>
+#include <libdvben50221/en50221_stdcam.h>
+#include "zap_ca.h"
+
+
+static int zap_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids);
+static int zap_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string);
+static void *camthread_func(void* arg);
+
+static struct en50221_transport_layer *tl = NULL;
+static struct en50221_session_layer *sl = NULL;
+static struct en50221_stdcam *stdcam = NULL;
+
+static int ca_resource_connected = 0;
+
+static int camthread_shutdown = 0;
+static pthread_t camthread;
+static int seenpmt = 0;
+static int moveca = 0;
+
+void zap_ca_start(struct zap_ca_params *params)
+{
+ // create transport layer
+ tl = en50221_tl_create(1, 16);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ return;
+ }
+
+ // create session layer
+ sl = en50221_sl_create(tl, 16);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ en50221_tl_destroy(tl);
+ return;
+ }
+
+ // create the stdcam instance
+ stdcam = en50221_stdcam_create(params->adapter_id, params->caslot_num, tl, sl);
+ if (stdcam == NULL) {
+ en50221_sl_destroy(sl);
+ en50221_tl_destroy(tl);
+ return;
+ }
+
+ // hook up the AI callbacks
+ if (stdcam->ai_resource) {
+ en50221_app_ai_register_callback(stdcam->ai_resource, zap_ai_callback, stdcam);
+ }
+
+ // hook up the CA callbacks
+ if (stdcam->ca_resource) {
+ en50221_app_ca_register_info_callback(stdcam->ca_resource, zap_ca_info_callback, stdcam);
+ }
+
+ // any other stuff
+ moveca = params->moveca;
+
+ // start the cam thread
+ pthread_create(&camthread, NULL, camthread_func, NULL);
+}
+
+void zap_ca_stop(void)
+{
+ if (stdcam == NULL)
+ return;
+
+ // shutdown the cam thread
+ camthread_shutdown = 1;
+ pthread_join(camthread, NULL);
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ // destroy the stdcam
+ if (stdcam->destroy)
+ stdcam->destroy(stdcam, 1);
+}
+
+int zap_ca_new_pmt(struct mpeg_pmt_section *pmt)
+{
+ uint8_t capmt[4096];
+ int size;
+
+ if (stdcam == NULL)
+ return -1;
+
+ if (ca_resource_connected) {
+ fprintf(stderr, "Received new PMT - sending to CAM...\n");
+
+ // translate it into a CA PMT
+ int listmgmt = CA_LIST_MANAGEMENT_ONLY;
+ if (seenpmt) {
+ listmgmt = CA_LIST_MANAGEMENT_UPDATE;
+ }
+ seenpmt = 1;
+
+ if ((size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), moveca, listmgmt,
+ CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
+ fprintf(stderr, "Failed to format PMT\n");
+ return -1;
+ }
+
+ // set it
+ if (en50221_app_ca_pmt(stdcam->ca_resource, stdcam->ca_session_number, capmt, size)) {
+ fprintf(stderr, "Failed to send PMT\n");
+ return -1;
+ }
+
+ // we've seen this PMT
+ return 1;
+ }
+
+ return 0;
+}
+
+void zap_ca_new_dvbtime(time_t dvb_time)
+{
+ if (stdcam == NULL)
+ return;
+
+ if (stdcam->dvbtime)
+ stdcam->dvbtime(stdcam, dvb_time);
+}
+
+static void *camthread_func(void* arg)
+{
+ (void) arg;
+
+ while(!camthread_shutdown) {
+ stdcam->poll(stdcam);
+ }
+
+ return 0;
+}
+
+static int zap_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ printf("CAM Application type: %02x\n", application_type);
+ printf("CAM Application manufacturer: %04x\n", application_manufacturer);
+ printf("CAM Manufacturer code: %04x\n", manufacturer_code);
+ printf("CAM Menu string: %.*s\n", menu_string_length, menu_string);
+
+ return 0;
+}
+
+static int zap_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids)
+{
+ (void) arg;
+ (void) slot_id;
+ (void) session_number;
+
+ printf("CAM supports the following ca system ids:\n");
+ uint32_t i;
+ for(i=0; i< ca_id_count; i++) {
+ printf(" 0x%04x\n", ca_ids[i]);
+ }
+ ca_resource_connected = 1;
+ return 0;
+}
diff --git a/util/zap/zap_ca.h b/util/zap/zap_ca.h
new file mode 100644
index 0000000..5df45fd
--- /dev/null
+++ b/util/zap/zap_ca.h
@@ -0,0 +1,37 @@
+/*
+ ZAP utility CA functions
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef ZAP_CA_H
+#define ZAP_CA_H 1
+
+struct zap_ca_params {
+ int adapter_id;
+ int caslot_num;
+ int moveca;
+};
+
+extern void zap_ca_start(struct zap_ca_params *params);
+extern void zap_ca_stop(void);
+
+extern int zap_ca_new_pmt(struct mpeg_pmt_section *pmt);
+extern void zap_ca_new_dvbtime(time_t dvb_time);
+
+#endif
diff --git a/util/zap/zap_dvb.c b/util/zap/zap_dvb.c
new file mode 100644
index 0000000..677e05e
--- /dev/null
+++ b/util/zap/zap_dvb.c
@@ -0,0 +1,353 @@
+/*
+ ZAP utility DVB functions
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/poll.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libucsi/section.h>
+#include <libucsi/mpeg/section.h>
+#include <libucsi/dvb/section.h>
+#include "zap_dvb.h"
+#include "zap_ca.h"
+
+#define FE_STATUS_PARAMS (DVBFE_INFO_LOCKSTATUS|DVBFE_INFO_SIGNAL_STRENGTH|DVBFE_INFO_BER|DVBFE_INFO_SNR|DVBFE_INFO_UNCORRECTED_BLOCKS)
+
+static int dvbthread_shutdown = 0;
+static pthread_t dvbthread;
+
+static int pat_version = -1;
+static int ca_pmt_version = -1;
+
+static void *dvbthread_func(void* arg);
+
+static void process_pat(int pat_fd, struct zap_dvb_params *params, int *pmt_fd, struct pollfd *pollfd);
+static void process_tdt(int tdt_fd);
+static void process_pmt(int pmt_fd, struct zap_dvb_params *params);
+static int create_section_filter(int adapter, int demux, uint16_t pid, uint8_t table_id);
+
+
+int zap_dvb_start(struct zap_dvb_params *params)
+{
+ pthread_create(&dvbthread, NULL, dvbthread_func, (void*) params);
+ return 0;
+}
+
+void zap_dvb_stop(void)
+{
+ dvbthread_shutdown = 1;
+ pthread_join(dvbthread, NULL);
+}
+
+static void *dvbthread_func(void* arg)
+{
+ int tune_state = 0;
+ int pat_fd = -1;
+ int pmt_fd = -1;
+ int tdt_fd = -1;
+ struct pollfd pollfds[3];
+
+ struct zap_dvb_params *params = (struct zap_dvb_params *) arg;
+
+ // create PAT filter
+ if ((pat_fd = create_section_filter(params->adapter_id, params->demux_id,
+ TRANSPORT_PAT_PID, stag_mpeg_program_association)) < 0) {
+ fprintf(stderr, "Failed to create PAT section filter\n");
+ exit(1);
+ }
+ pollfds[0].fd = pat_fd;
+ pollfds[0].events = POLLIN|POLLPRI|POLLERR;
+
+ // create TDT filter
+ if ((tdt_fd = create_section_filter(params->adapter_id, params->demux_id, TRANSPORT_TDT_PID, stag_dvb_time_date)) < 0) {
+ fprintf(stderr, "Failed to create TDT section filter\n");
+ exit(1);
+ }
+ pollfds[1].fd = tdt_fd;
+ pollfds[1].events = POLLIN|POLLPRI|POLLERR;
+
+ // zero PMT filter
+ pollfds[2].fd = 0;
+ pollfds[2].events = 0;
+
+ // the DVB loop
+ while(!dvbthread_shutdown) {
+ // tune frontend + monitor lock status
+ if (tune_state == 0) {
+ // get the type of frontend
+ struct dvbfe_info result;
+ char *types;
+ memset(&result, 0, sizeof(result));
+ dvbfe_get_info(params->fe, 0, &result, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
+ switch(result.type) {
+ case DVBFE_TYPE_DVBS:
+ types = "DVB-S";
+ break;
+ case DVBFE_TYPE_DVBC:
+ types = "DVB-C";
+ break;
+ case DVBFE_TYPE_DVBT:
+ types = "DVB-T";
+ break;
+ case DVBFE_TYPE_ATSC:
+ types = "ATSC";
+ break;
+ default:
+ types = "Unknown";
+ }
+ fprintf(stderr, "Using frontend \"%s\", type %s\n", result.name, types);
+
+ // do we have a valid SEC configuration?
+ struct dvbsec_config *sec = NULL;
+ if (params->valid_sec)
+ sec = &params->sec;
+
+ // tune!
+ if (dvbsec_set(params->fe,
+ sec,
+ params->channel.polarization,
+ (params->channel.diseqc_switch & 0x01) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
+ (params->channel.diseqc_switch & 0x02) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
+ &params->channel.fe_params,
+ 0)) {
+ fprintf(stderr, "Failed to set frontend\n");
+ exit(1);
+ }
+
+ tune_state++;
+ } else if (tune_state == 1) {
+ struct dvbfe_info result;
+ memset(&result, 0, sizeof(result));
+ if (dvbfe_get_info(params->fe,
+ FE_STATUS_PARAMS,
+ &result,
+ DVBFE_INFO_QUERYTYPE_IMMEDIATE,
+ 0) != FE_STATUS_PARAMS) {
+ fprintf(stderr, "Problem retrieving frontend information: %m\n");
+ }
+
+ fprintf(stderr, "status %c%c%c%c%c | signal %04x | snr %04x | ber %08x | unc %08x | %s\r",
+ result.signal ? 'S' : ' ',
+ result.carrier ? 'C' : ' ',
+ result.viterbi ? 'V' : ' ',
+ result.sync ? 'Y' : ' ',
+ result.lock ? 'L' : ' ',
+ result.signal_strength,
+ result.snr,
+ result.ber,
+ result.ucblocks,
+ result.lock ? "FE_HAS_LOCK" : "");
+ fflush(stderr);
+
+ if (result.lock) {
+ tune_state++;
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ } else {
+ usleep(500000);
+ }
+ }
+
+ // is there SI data?
+ int count = poll(pollfds, 3, 100);
+ if (count < 0) {
+ fprintf(stderr, "Poll error\n");
+ break;
+ }
+ if (count == 0) {
+ continue;
+ }
+
+ // PAT
+ if (pollfds[0].revents & (POLLIN|POLLPRI)) {
+ process_pat(pat_fd, params, &pmt_fd, &pollfds[2]);
+ }
+
+ // TDT
+ if (pollfds[1].revents & (POLLIN|POLLPRI)) {
+ process_tdt(tdt_fd);
+ }
+
+ // PMT
+ if (pollfds[2].revents & (POLLIN|POLLPRI)) {
+ process_pmt(pmt_fd, params);
+ }
+ }
+
+ // close demuxers
+ if (pat_fd != -1)
+ close(pat_fd);
+ if (pmt_fd != -1)
+ close(pmt_fd);
+ if (tdt_fd != -1)
+ close(tdt_fd);
+
+ return 0;
+}
+
+static void process_pat(int pat_fd, struct zap_dvb_params *params, int *pmt_fd, struct pollfd *pollfd)
+{
+ int size;
+ uint8_t sibuf[4096];
+
+ // read the section
+ if ((size = read(pat_fd, sibuf, sizeof(sibuf))) < 0) {
+ return;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ return;
+ }
+
+ // parse section_ext
+ struct section_ext *section_ext = section_ext_decode(section, 0);
+ if (section_ext == NULL) {
+ return;
+ }
+ if (pat_version == section_ext->version_number) {
+ return;
+ }
+
+ // parse PAT
+ struct mpeg_pat_section *pat = mpeg_pat_section_codec(section_ext);
+ if (pat == NULL) {
+ return;
+ }
+
+ // try and find the requested program
+ struct mpeg_pat_program *cur_program;
+ mpeg_pat_section_programs_for_each(pat, cur_program) {
+ if (cur_program->program_number == params->channel.service_id) {
+ // close old PMT fd
+ if (*pmt_fd != -1)
+ close(*pmt_fd);
+
+ // create PMT filter
+ if ((*pmt_fd = create_section_filter(params->adapter_id, params->demux_id,
+ cur_program->pid, stag_mpeg_program_map)) < 0) {
+ return;
+ }
+ pollfd->fd = *pmt_fd;
+ pollfd->events = POLLIN|POLLPRI|POLLERR;
+
+ // we have a new PMT pid
+ ca_pmt_version = -1;
+ break;
+ }
+ }
+
+ // remember the PAT version
+ pat_version = section_ext->version_number;
+}
+
+static void process_tdt(int tdt_fd)
+{
+ int size;
+ uint8_t sibuf[4096];
+
+ // read the section
+ if ((size = read(tdt_fd, sibuf, sizeof(sibuf))) < 0) {
+ return;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ return;
+ }
+
+ // parse TDT
+ struct dvb_tdt_section *tdt = dvb_tdt_section_codec(section);
+ if (tdt == NULL) {
+ return;
+ }
+
+ // done
+ zap_ca_new_dvbtime(dvbdate_to_unixtime(tdt->utc_time));
+}
+
+static void process_pmt(int pmt_fd, struct zap_dvb_params *params)
+{
+ int size;
+ uint8_t sibuf[4096];
+
+ // read the section
+ if ((size = read(pmt_fd, sibuf, sizeof(sibuf))) < 0) {
+ return;
+ }
+
+ // parse section
+ struct section *section = section_codec(sibuf, size);
+ if (section == NULL) {
+ return;
+ }
+
+ // parse section_ext
+ struct section_ext *section_ext = section_ext_decode(section, 0);
+ if (section_ext == NULL) {
+ return;
+ }
+ if ((section_ext->table_id_ext != params->channel.service_id) ||
+ (section_ext->version_number == ca_pmt_version)) {
+ return;
+ }
+
+ // parse PMT
+ struct mpeg_pmt_section *pmt = mpeg_pmt_section_codec(section_ext);
+ if (pmt == NULL) {
+ return;
+ }
+
+ // do ca handling
+ if (zap_ca_new_pmt(pmt) == 1)
+ ca_pmt_version = pmt->head.version_number;
+}
+
+static int create_section_filter(int adapter, int demux, uint16_t pid, uint8_t table_id)
+{
+ int demux_fd = -1;
+ uint8_t filter[18];
+ uint8_t mask[18];
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ return -1;
+ }
+
+ // create a section filter
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = table_id;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(demux_fd, pid, filter, mask, 1, 1)) {
+ close(demux_fd);
+ return -1;
+ }
+
+ // done
+ return demux_fd;
+}
diff --git a/util/zap/zap_dvb.h b/util/zap/zap_dvb.h
new file mode 100644
index 0000000..d2a219a
--- /dev/null
+++ b/util/zap/zap_dvb.h
@@ -0,0 +1,41 @@
+/*
+ ZAP utility DVB functions
+
+ Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef ZAP_DVB_H
+#define ZAP_DVB_H 1
+
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+#include <libdvbsec/dvbsec_api.h>
+
+struct zap_dvb_params {
+ int adapter_id;
+ int frontend_id;
+ int demux_id;
+ struct dvbcfg_zapchannel channel;
+ struct dvbsec_config sec;
+ int valid_sec;
+ struct dvbfe_handle *fe;
+};
+
+extern int zap_dvb_start(struct zap_dvb_params *params);
+extern void zap_dvb_stop(void);
+
+#endif