162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * This file contains the logic to work with MPEG Program-Specific Information.
462306a36Sopenharmony_ci * These are defined both in ISO/IEC 13818-1 (systems) and ETSI EN 300 468.
562306a36Sopenharmony_ci * PSI is carried in the form of table structures, and although each table might
662306a36Sopenharmony_ci * technically be broken into one or more sections, we do not do this here,
762306a36Sopenharmony_ci * hence 'table' and 'section' are interchangeable for vidtv.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Copyright (C) 2020 Daniel W. S. Almeida
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifndef VIDTV_PSI_H
1362306a36Sopenharmony_ci#define VIDTV_PSI_H
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/types.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/*
1862306a36Sopenharmony_ci * all section lengths start immediately after the 'section_length' field
1962306a36Sopenharmony_ci * see ISO/IEC 13818-1 : 2000 and ETSI EN 300 468 V 1.10.1 for
2062306a36Sopenharmony_ci * reference
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci#define PAT_LEN_UNTIL_LAST_SECTION_NUMBER 5
2362306a36Sopenharmony_ci#define PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH 9
2462306a36Sopenharmony_ci#define SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE 8
2562306a36Sopenharmony_ci#define NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN 7
2662306a36Sopenharmony_ci#define EIT_LEN_UNTIL_LAST_TABLE_ID 11
2762306a36Sopenharmony_ci#define MAX_SECTION_LEN 1021
2862306a36Sopenharmony_ci#define EIT_MAX_SECTION_LEN 4093 /* see ETSI 300 468 v.1.10.1 p. 26 */
2962306a36Sopenharmony_ci#define VIDTV_PAT_PID 0 /* mandated by the specs */
3062306a36Sopenharmony_ci#define VIDTV_SDT_PID 0x0011 /* mandated by the specs */
3162306a36Sopenharmony_ci#define VIDTV_NIT_PID 0x0010 /* mandated by the specs */
3262306a36Sopenharmony_ci#define VIDTV_EIT_PID 0x0012 /*mandated by the specs */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cienum vidtv_psi_descriptors {
3562306a36Sopenharmony_ci	REGISTRATION_DESCRIPTOR	= 0x05, /* See ISO/IEC 13818-1 section 2.6.8 */
3662306a36Sopenharmony_ci	NETWORK_NAME_DESCRIPTOR = 0x40, /* See ETSI EN 300 468 section 6.2.27 */
3762306a36Sopenharmony_ci	SERVICE_LIST_DESCRIPTOR = 0x41, /* See ETSI EN 300 468 section 6.2.35 */
3862306a36Sopenharmony_ci	SERVICE_DESCRIPTOR = 0x48, /* See ETSI EN 300 468 section 6.2.33 */
3962306a36Sopenharmony_ci	SHORT_EVENT_DESCRIPTOR = 0x4d, /* See ETSI EN 300 468 section 6.2.37 */
4062306a36Sopenharmony_ci};
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cienum vidtv_psi_stream_types {
4362306a36Sopenharmony_ci	STREAM_PRIVATE_DATA = 0x06, /* see ISO/IEC 13818-1 2000 p. 48 */
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/*
4762306a36Sopenharmony_ci * struct vidtv_psi_desc - A generic PSI descriptor type.
4862306a36Sopenharmony_ci * The descriptor length is an 8-bit field specifying the total number of bytes of the data portion
4962306a36Sopenharmony_ci * of the descriptor following the byte defining the value of this field.
5062306a36Sopenharmony_ci */
5162306a36Sopenharmony_cistruct vidtv_psi_desc {
5262306a36Sopenharmony_ci	struct vidtv_psi_desc *next;
5362306a36Sopenharmony_ci	u8 type;
5462306a36Sopenharmony_ci	u8 length;
5562306a36Sopenharmony_ci	u8 data[];
5662306a36Sopenharmony_ci} __packed;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/*
5962306a36Sopenharmony_ci * struct vidtv_psi_desc_service - Service descriptor.
6062306a36Sopenharmony_ci * See ETSI EN 300 468 section 6.2.33.
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_cistruct vidtv_psi_desc_service {
6362306a36Sopenharmony_ci	struct vidtv_psi_desc *next;
6462306a36Sopenharmony_ci	u8 type;
6562306a36Sopenharmony_ci	u8 length;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	u8 service_type;
6862306a36Sopenharmony_ci	u8 provider_name_len;
6962306a36Sopenharmony_ci	char *provider_name;
7062306a36Sopenharmony_ci	u8 service_name_len;
7162306a36Sopenharmony_ci	char *service_name;
7262306a36Sopenharmony_ci} __packed;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/*
7562306a36Sopenharmony_ci * struct vidtv_psi_desc_registration - A registration descriptor.
7662306a36Sopenharmony_ci * See ISO/IEC 13818-1 section 2.6.8
7762306a36Sopenharmony_ci */
7862306a36Sopenharmony_cistruct vidtv_psi_desc_registration {
7962306a36Sopenharmony_ci	struct vidtv_psi_desc *next;
8062306a36Sopenharmony_ci	u8 type;
8162306a36Sopenharmony_ci	u8 length;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/*
8462306a36Sopenharmony_ci	 * The format_identifier is a 32-bit value obtained from a Registration
8562306a36Sopenharmony_ci	 * Authority as designated by ISO/IEC JTC 1/SC 29.
8662306a36Sopenharmony_ci	 */
8762306a36Sopenharmony_ci	__be32 format_id;
8862306a36Sopenharmony_ci	/*
8962306a36Sopenharmony_ci	 * The meaning of additional_identification_info bytes, if any, are
9062306a36Sopenharmony_ci	 * defined by the assignee of that format_identifier, and once defined
9162306a36Sopenharmony_ci	 * they shall not change.
9262306a36Sopenharmony_ci	 */
9362306a36Sopenharmony_ci	u8 additional_identification_info[];
9462306a36Sopenharmony_ci} __packed;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/*
9762306a36Sopenharmony_ci * struct vidtv_psi_desc_network_name - A network name descriptor
9862306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 6.2.27
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_cistruct vidtv_psi_desc_network_name {
10162306a36Sopenharmony_ci	struct vidtv_psi_desc *next;
10262306a36Sopenharmony_ci	u8 type;
10362306a36Sopenharmony_ci	u8 length;
10462306a36Sopenharmony_ci	char *network_name;
10562306a36Sopenharmony_ci} __packed;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistruct vidtv_psi_desc_service_list_entry {
10862306a36Sopenharmony_ci	__be16 service_id;
10962306a36Sopenharmony_ci	u8 service_type;
11062306a36Sopenharmony_ci	struct vidtv_psi_desc_service_list_entry *next;
11162306a36Sopenharmony_ci} __packed;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/*
11462306a36Sopenharmony_ci * struct vidtv_psi_desc_service_list - A service list descriptor
11562306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 6.2.35
11662306a36Sopenharmony_ci */
11762306a36Sopenharmony_cistruct vidtv_psi_desc_service_list {
11862306a36Sopenharmony_ci	struct vidtv_psi_desc *next;
11962306a36Sopenharmony_ci	u8 type;
12062306a36Sopenharmony_ci	u8 length;
12162306a36Sopenharmony_ci	struct vidtv_psi_desc_service_list_entry *service_list;
12262306a36Sopenharmony_ci} __packed;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/*
12562306a36Sopenharmony_ci * struct vidtv_psi_desc_short_event - A short event descriptor
12662306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 6.2.37
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_cistruct vidtv_psi_desc_short_event {
12962306a36Sopenharmony_ci	struct vidtv_psi_desc *next;
13062306a36Sopenharmony_ci	u8 type;
13162306a36Sopenharmony_ci	u8 length;
13262306a36Sopenharmony_ci	char *iso_language_code;
13362306a36Sopenharmony_ci	u8 event_name_len;
13462306a36Sopenharmony_ci	char *event_name;
13562306a36Sopenharmony_ci	u8 text_len;
13662306a36Sopenharmony_ci	char *text;
13762306a36Sopenharmony_ci} __packed;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cistruct vidtv_psi_desc_short_event
14062306a36Sopenharmony_ci*vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head,
14162306a36Sopenharmony_ci				 char *iso_language_code,
14262306a36Sopenharmony_ci				 char *event_name,
14362306a36Sopenharmony_ci				 char *text);
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/*
14662306a36Sopenharmony_ci * struct vidtv_psi_table_header - A header that is present for all PSI tables.
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_cistruct vidtv_psi_table_header {
14962306a36Sopenharmony_ci	u8  table_id;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	__be16 bitfield; /* syntax: 1, zero: 1, one: 2, section_length: 13 */
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	__be16 id; /* TS ID */
15462306a36Sopenharmony_ci	u8  current_next:1;
15562306a36Sopenharmony_ci	u8  version:5;
15662306a36Sopenharmony_ci	u8  one2:2;
15762306a36Sopenharmony_ci	u8  section_id;	/* section_number */
15862306a36Sopenharmony_ci	u8  last_section; /* last_section_number */
15962306a36Sopenharmony_ci} __packed;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/*
16262306a36Sopenharmony_ci * struct vidtv_psi_table_pat_program - A single program in the PAT
16362306a36Sopenharmony_ci * See ISO/IEC 13818-1 : 2000 p.43
16462306a36Sopenharmony_ci */
16562306a36Sopenharmony_cistruct vidtv_psi_table_pat_program {
16662306a36Sopenharmony_ci	__be16 service_id;
16762306a36Sopenharmony_ci	__be16 bitfield; /* reserved: 3, program_map_pid/network_pid: 13 */
16862306a36Sopenharmony_ci	struct vidtv_psi_table_pat_program *next;
16962306a36Sopenharmony_ci} __packed;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci/*
17262306a36Sopenharmony_ci * struct vidtv_psi_table_pat - The Program Allocation Table (PAT)
17362306a36Sopenharmony_ci * See ISO/IEC 13818-1 : 2000 p.43
17462306a36Sopenharmony_ci */
17562306a36Sopenharmony_cistruct vidtv_psi_table_pat {
17662306a36Sopenharmony_ci	struct vidtv_psi_table_header header;
17762306a36Sopenharmony_ci	u16 num_pat;
17862306a36Sopenharmony_ci	u16 num_pmt;
17962306a36Sopenharmony_ci	struct vidtv_psi_table_pat_program *program;
18062306a36Sopenharmony_ci} __packed;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci/*
18362306a36Sopenharmony_ci * struct vidtv_psi_table_sdt_service - Represents a service in the SDT.
18462306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 5.2.3.
18562306a36Sopenharmony_ci */
18662306a36Sopenharmony_cistruct vidtv_psi_table_sdt_service {
18762306a36Sopenharmony_ci	__be16 service_id;
18862306a36Sopenharmony_ci	u8 EIT_present_following:1;
18962306a36Sopenharmony_ci	u8 EIT_schedule:1;
19062306a36Sopenharmony_ci	u8 reserved:6;
19162306a36Sopenharmony_ci	__be16 bitfield; /* running_status: 3, free_ca:1, desc_loop_len:12 */
19262306a36Sopenharmony_ci	struct vidtv_psi_desc *descriptor;
19362306a36Sopenharmony_ci	struct vidtv_psi_table_sdt_service *next;
19462306a36Sopenharmony_ci} __packed;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/*
19762306a36Sopenharmony_ci * struct vidtv_psi_table_sdt - Represents the Service Description Table
19862306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 5.2.3.
19962306a36Sopenharmony_ci */
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistruct vidtv_psi_table_sdt {
20262306a36Sopenharmony_ci	struct vidtv_psi_table_header header;
20362306a36Sopenharmony_ci	__be16 network_id; /* original_network_id */
20462306a36Sopenharmony_ci	u8  reserved;
20562306a36Sopenharmony_ci	struct vidtv_psi_table_sdt_service *service;
20662306a36Sopenharmony_ci} __packed;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci/*
20962306a36Sopenharmony_ci * enum service_running_status - Status of a SDT service.
21062306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 5.2.3 table 6.
21162306a36Sopenharmony_ci */
21262306a36Sopenharmony_cienum service_running_status {
21362306a36Sopenharmony_ci	RUNNING = 0x4,
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci/*
21762306a36Sopenharmony_ci * enum service_type - The type of a SDT service.
21862306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 6.2.33, table 81.
21962306a36Sopenharmony_ci */
22062306a36Sopenharmony_cienum service_type {
22162306a36Sopenharmony_ci	/* see ETSI EN 300 468 v1.15.1 p. 77 */
22262306a36Sopenharmony_ci	DIGITAL_TELEVISION_SERVICE = 0x1,
22362306a36Sopenharmony_ci	DIGITAL_RADIO_SOUND_SERVICE = 0X2,
22462306a36Sopenharmony_ci};
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci/*
22762306a36Sopenharmony_ci * struct vidtv_psi_table_pmt_stream - A single stream in the PMT.
22862306a36Sopenharmony_ci * See ISO/IEC 13818-1 : 2000 p.46.
22962306a36Sopenharmony_ci */
23062306a36Sopenharmony_cistruct vidtv_psi_table_pmt_stream {
23162306a36Sopenharmony_ci	u8 type;
23262306a36Sopenharmony_ci	__be16 bitfield; /* reserved: 3, elementary_pid: 13 */
23362306a36Sopenharmony_ci	__be16 bitfield2; /*reserved: 4, zero: 2, desc_length: 10 */
23462306a36Sopenharmony_ci	struct vidtv_psi_desc *descriptor;
23562306a36Sopenharmony_ci	struct vidtv_psi_table_pmt_stream *next;
23662306a36Sopenharmony_ci} __packed;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci/*
23962306a36Sopenharmony_ci * struct vidtv_psi_table_pmt - The Program Map Table (PMT).
24062306a36Sopenharmony_ci * See ISO/IEC 13818-1 : 2000 p.46.
24162306a36Sopenharmony_ci */
24262306a36Sopenharmony_cistruct vidtv_psi_table_pmt {
24362306a36Sopenharmony_ci	struct vidtv_psi_table_header header;
24462306a36Sopenharmony_ci	__be16 bitfield; /* reserved:3, pcr_pid: 13 */
24562306a36Sopenharmony_ci	__be16 bitfield2; /* reserved: 4, zero: 2, desc_len: 10 */
24662306a36Sopenharmony_ci	struct vidtv_psi_desc *descriptor;
24762306a36Sopenharmony_ci	struct vidtv_psi_table_pmt_stream *stream;
24862306a36Sopenharmony_ci} __packed;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci/**
25162306a36Sopenharmony_ci * struct psi_write_args - Arguments for the PSI packetizer.
25262306a36Sopenharmony_ci * @dest_buf: The buffer to write into.
25362306a36Sopenharmony_ci * @from: PSI data to be copied.
25462306a36Sopenharmony_ci * @len: How much to write.
25562306a36Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer.
25662306a36Sopenharmony_ci * @pid: TS packet ID.
25762306a36Sopenharmony_ci * @new_psi_section: Set when starting a table section.
25862306a36Sopenharmony_ci * @continuity_counter: Incremented on every new packet.
25962306a36Sopenharmony_ci * @is_crc: Set when writing the CRC at the end.
26062306a36Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer
26162306a36Sopenharmony_ci * @crc: a pointer to store the crc for this chunk
26262306a36Sopenharmony_ci */
26362306a36Sopenharmony_cistruct psi_write_args {
26462306a36Sopenharmony_ci	void *dest_buf;
26562306a36Sopenharmony_ci	void *from;
26662306a36Sopenharmony_ci	size_t len;
26762306a36Sopenharmony_ci	u32 dest_offset;
26862306a36Sopenharmony_ci	u16 pid;
26962306a36Sopenharmony_ci	bool new_psi_section;
27062306a36Sopenharmony_ci	u8 *continuity_counter;
27162306a36Sopenharmony_ci	bool is_crc;
27262306a36Sopenharmony_ci	u32 dest_buf_sz;
27362306a36Sopenharmony_ci	u32 *crc;
27462306a36Sopenharmony_ci};
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/**
27762306a36Sopenharmony_ci * struct desc_write_args - Arguments in order to write a descriptor.
27862306a36Sopenharmony_ci * @dest_buf: The buffer to write into.
27962306a36Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer.
28062306a36Sopenharmony_ci * @desc: A pointer to the descriptor
28162306a36Sopenharmony_ci * @pid: TS packet ID.
28262306a36Sopenharmony_ci * @continuity_counter: Incremented on every new packet.
28362306a36Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer
28462306a36Sopenharmony_ci * @crc: a pointer to store the crc for this chunk
28562306a36Sopenharmony_ci */
28662306a36Sopenharmony_cistruct desc_write_args {
28762306a36Sopenharmony_ci	void *dest_buf;
28862306a36Sopenharmony_ci	u32 dest_offset;
28962306a36Sopenharmony_ci	struct vidtv_psi_desc *desc;
29062306a36Sopenharmony_ci	u16 pid;
29162306a36Sopenharmony_ci	u8 *continuity_counter;
29262306a36Sopenharmony_ci	u32 dest_buf_sz;
29362306a36Sopenharmony_ci	u32 *crc;
29462306a36Sopenharmony_ci};
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci/**
29762306a36Sopenharmony_ci * struct crc32_write_args - Arguments in order to write the CRC at the end of
29862306a36Sopenharmony_ci * the PSI tables.
29962306a36Sopenharmony_ci * @dest_buf: The buffer to write into.
30062306a36Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer.
30162306a36Sopenharmony_ci * @crc: the CRC value to write
30262306a36Sopenharmony_ci * @pid: TS packet ID.
30362306a36Sopenharmony_ci * @continuity_counter: Incremented on every new packet.
30462306a36Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer
30562306a36Sopenharmony_ci */
30662306a36Sopenharmony_cistruct crc32_write_args {
30762306a36Sopenharmony_ci	void *dest_buf;
30862306a36Sopenharmony_ci	u32 dest_offset;
30962306a36Sopenharmony_ci	__be32 crc;
31062306a36Sopenharmony_ci	u16 pid;
31162306a36Sopenharmony_ci	u8 *continuity_counter;
31262306a36Sopenharmony_ci	u32 dest_buf_sz;
31362306a36Sopenharmony_ci};
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci/**
31662306a36Sopenharmony_ci * struct header_write_args - Arguments in order to write the common table
31762306a36Sopenharmony_ci * header
31862306a36Sopenharmony_ci * @dest_buf: The buffer to write into.
31962306a36Sopenharmony_ci * @dest_offset: where to start writing in the dest_buffer.
32062306a36Sopenharmony_ci * @h: a pointer to the header.
32162306a36Sopenharmony_ci * @pid: TS packet ID.
32262306a36Sopenharmony_ci * @continuity_counter: Incremented on every new packet.
32362306a36Sopenharmony_ci * @dest_buf_sz: The size of the dest_buffer
32462306a36Sopenharmony_ci * @crc: a pointer to store the crc for this chunk
32562306a36Sopenharmony_ci */
32662306a36Sopenharmony_cistruct header_write_args {
32762306a36Sopenharmony_ci	void *dest_buf;
32862306a36Sopenharmony_ci	u32 dest_offset;
32962306a36Sopenharmony_ci	struct vidtv_psi_table_header *h;
33062306a36Sopenharmony_ci	u16 pid;
33162306a36Sopenharmony_ci	u8 *continuity_counter;
33262306a36Sopenharmony_ci	u32 dest_buf_sz;
33362306a36Sopenharmony_ci	u32 *crc;
33462306a36Sopenharmony_ci};
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_cistruct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc *head,
33762306a36Sopenharmony_ci							   enum service_type service_type,
33862306a36Sopenharmony_ci							   char *service_name,
33962306a36Sopenharmony_ci							   char *provider_name);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistruct vidtv_psi_desc_registration
34262306a36Sopenharmony_ci*vidtv_psi_registration_desc_init(struct vidtv_psi_desc *head,
34362306a36Sopenharmony_ci				  __be32 format_id,
34462306a36Sopenharmony_ci				  u8 *additional_ident_info,
34562306a36Sopenharmony_ci				  u32 additional_info_len);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_cistruct vidtv_psi_desc_network_name
34862306a36Sopenharmony_ci*vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistruct vidtv_psi_desc_service_list
35162306a36Sopenharmony_ci*vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head,
35262306a36Sopenharmony_ci				  struct vidtv_psi_desc_service_list_entry *entry);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cistruct vidtv_psi_table_pat_program
35562306a36Sopenharmony_ci*vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head,
35662306a36Sopenharmony_ci			    u16 service_id,
35762306a36Sopenharmony_ci			    u16 program_map_pid);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_cistruct vidtv_psi_table_pmt_stream*
36062306a36Sopenharmony_cividtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head,
36162306a36Sopenharmony_ci			  enum vidtv_psi_stream_types stream_type,
36262306a36Sopenharmony_ci			  u16 es_pid);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_cistruct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id);
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_cistruct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number,
36762306a36Sopenharmony_ci						     u16 pcr_pid);
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_cistruct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id,
37062306a36Sopenharmony_ci						     u16 transport_stream_id);
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistruct vidtv_psi_table_sdt_service*
37362306a36Sopenharmony_cividtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head,
37462306a36Sopenharmony_ci			   u16 service_id,
37562306a36Sopenharmony_ci			   bool eit_schedule,
37662306a36Sopenharmony_ci			   bool eit_present_following);
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_civoid
37962306a36Sopenharmony_cividtv_psi_desc_destroy(struct vidtv_psi_desc *desc);
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_civoid
38262306a36Sopenharmony_cividtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p);
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_civoid
38562306a36Sopenharmony_cividtv_psi_pat_table_destroy(struct vidtv_psi_table_pat *p);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_civoid
38862306a36Sopenharmony_cividtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s);
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_civoid
39162306a36Sopenharmony_cividtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_civoid
39462306a36Sopenharmony_cividtv_psi_sdt_table_destroy(struct vidtv_psi_table_sdt *sdt);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_civoid
39762306a36Sopenharmony_cividtv_psi_sdt_service_destroy(struct vidtv_psi_table_sdt_service *service);
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci/**
40062306a36Sopenharmony_ci * vidtv_psi_sdt_service_assign - Assigns the service loop to the SDT.
40162306a36Sopenharmony_ci * @sdt: The SDT to assign to.
40262306a36Sopenharmony_ci * @service: The service loop (one or more services)
40362306a36Sopenharmony_ci *
40462306a36Sopenharmony_ci * This will free the previous service loop in the table.
40562306a36Sopenharmony_ci * This will assign ownership of the service loop to the table, i.e. the table
40662306a36Sopenharmony_ci * will free this service loop when a call to its destroy function is made.
40762306a36Sopenharmony_ci */
40862306a36Sopenharmony_civoid
40962306a36Sopenharmony_cividtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt,
41062306a36Sopenharmony_ci			     struct vidtv_psi_table_sdt_service *service);
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci/**
41362306a36Sopenharmony_ci * vidtv_psi_desc_assign - Assigns a descriptor loop at some point
41462306a36Sopenharmony_ci * @to: Where to assign this descriptor loop to
41562306a36Sopenharmony_ci * @desc: The descriptor loop that will be assigned.
41662306a36Sopenharmony_ci *
41762306a36Sopenharmony_ci * This will free the loop in 'to', if any.
41862306a36Sopenharmony_ci */
41962306a36Sopenharmony_civoid vidtv_psi_desc_assign(struct vidtv_psi_desc **to,
42062306a36Sopenharmony_ci			   struct vidtv_psi_desc *desc);
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/**
42362306a36Sopenharmony_ci * vidtv_pmt_desc_assign - Assigns a descriptor loop at some point in a PMT section.
42462306a36Sopenharmony_ci * @pmt: The PMT section that will contain the descriptor loop
42562306a36Sopenharmony_ci * @to: Where in the PMT to assign this descriptor loop to
42662306a36Sopenharmony_ci * @desc: The descriptor loop that will be assigned.
42762306a36Sopenharmony_ci *
42862306a36Sopenharmony_ci * This will free the loop in 'to', if any.
42962306a36Sopenharmony_ci * This will assign ownership of the loop to the table, i.e. the table
43062306a36Sopenharmony_ci * will free this loop when a call to its destroy function is made.
43162306a36Sopenharmony_ci */
43262306a36Sopenharmony_civoid vidtv_pmt_desc_assign(struct vidtv_psi_table_pmt *pmt,
43362306a36Sopenharmony_ci			   struct vidtv_psi_desc **to,
43462306a36Sopenharmony_ci			   struct vidtv_psi_desc *desc);
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci/**
43762306a36Sopenharmony_ci * vidtv_sdt_desc_assign - Assigns a descriptor loop at some point in a SDT.
43862306a36Sopenharmony_ci * @sdt: The SDT that will contain the descriptor loop
43962306a36Sopenharmony_ci * @to: Where in the PMT to assign this descriptor loop to
44062306a36Sopenharmony_ci * @desc: The descriptor loop that will be assigned.
44162306a36Sopenharmony_ci *
44262306a36Sopenharmony_ci * This will free the loop in 'to', if any.
44362306a36Sopenharmony_ci * This will assign ownership of the loop to the table, i.e. the table
44462306a36Sopenharmony_ci * will free this loop when a call to its destroy function is made.
44562306a36Sopenharmony_ci */
44662306a36Sopenharmony_civoid vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt,
44762306a36Sopenharmony_ci			   struct vidtv_psi_desc **to,
44862306a36Sopenharmony_ci			   struct vidtv_psi_desc *desc);
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci/**
45162306a36Sopenharmony_ci * vidtv_psi_pat_program_assign - Assigns the program loop to the PAT.
45262306a36Sopenharmony_ci * @pat: The PAT to assign to.
45362306a36Sopenharmony_ci * @p: The program loop (one or more programs)
45462306a36Sopenharmony_ci *
45562306a36Sopenharmony_ci * This will free the previous program loop in the table.
45662306a36Sopenharmony_ci * This will assign ownership of the program loop to the table, i.e. the table
45762306a36Sopenharmony_ci * will free this program loop when a call to its destroy function is made.
45862306a36Sopenharmony_ci */
45962306a36Sopenharmony_civoid vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat,
46062306a36Sopenharmony_ci				  struct vidtv_psi_table_pat_program *p);
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci/**
46362306a36Sopenharmony_ci * vidtv_psi_pmt_stream_assign - Assigns the stream loop to the PAT.
46462306a36Sopenharmony_ci * @pmt: The PMT to assign to.
46562306a36Sopenharmony_ci * @s: The stream loop (one or more streams)
46662306a36Sopenharmony_ci *
46762306a36Sopenharmony_ci * This will free the previous stream loop in the table.
46862306a36Sopenharmony_ci * This will assign ownership of the stream loop to the table, i.e. the table
46962306a36Sopenharmony_ci * will free this stream loop when a call to its destroy function is made.
47062306a36Sopenharmony_ci */
47162306a36Sopenharmony_civoid vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt,
47262306a36Sopenharmony_ci				 struct vidtv_psi_table_pmt_stream *s);
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_cistruct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci/**
47762306a36Sopenharmony_ci * vidtv_psi_pmt_create_sec_for_each_pat_entry - Create a PMT section for each
47862306a36Sopenharmony_ci * program found in the PAT
47962306a36Sopenharmony_ci * @pat: The PAT to look for programs.
48062306a36Sopenharmony_ci * @pcr_pid: packet ID for the PCR to be used for the program described in this
48162306a36Sopenharmony_ci * PMT section
48262306a36Sopenharmony_ci */
48362306a36Sopenharmony_cistruct vidtv_psi_table_pmt**
48462306a36Sopenharmony_cividtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 pcr_pid);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci/**
48762306a36Sopenharmony_ci * vidtv_psi_pmt_get_pid - Get the TS PID for a PMT section.
48862306a36Sopenharmony_ci * @section: The PMT section whose PID we want to retrieve.
48962306a36Sopenharmony_ci * @pat: The PAT table to look into.
49062306a36Sopenharmony_ci *
49162306a36Sopenharmony_ci * Returns: the TS PID for 'section'
49262306a36Sopenharmony_ci */
49362306a36Sopenharmony_ciu16 vidtv_psi_pmt_get_pid(struct vidtv_psi_table_pmt *section,
49462306a36Sopenharmony_ci			  struct vidtv_psi_table_pat *pat);
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci/**
49762306a36Sopenharmony_ci * vidtv_psi_pat_table_update_sec_len - Recompute and update the PAT section length.
49862306a36Sopenharmony_ci * @pat: The PAT whose length is to be updated.
49962306a36Sopenharmony_ci *
50062306a36Sopenharmony_ci * This will traverse the table and accumulate the length of its components,
50162306a36Sopenharmony_ci * which is then used to replace the 'section_length' field.
50262306a36Sopenharmony_ci *
50362306a36Sopenharmony_ci * If section_length > MAX_SECTION_LEN, the operation fails.
50462306a36Sopenharmony_ci */
50562306a36Sopenharmony_civoid vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci/**
50862306a36Sopenharmony_ci * vidtv_psi_pmt_table_update_sec_len - Recompute and update the PMT section length.
50962306a36Sopenharmony_ci * @pmt: The PMT whose length is to be updated.
51062306a36Sopenharmony_ci *
51162306a36Sopenharmony_ci * This will traverse the table and accumulate the length of its components,
51262306a36Sopenharmony_ci * which is then used to replace the 'section_length' field.
51362306a36Sopenharmony_ci *
51462306a36Sopenharmony_ci * If section_length > MAX_SECTION_LEN, the operation fails.
51562306a36Sopenharmony_ci */
51662306a36Sopenharmony_civoid vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt);
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci/**
51962306a36Sopenharmony_ci * vidtv_psi_sdt_table_update_sec_len - Recompute and update the SDT section length.
52062306a36Sopenharmony_ci * @sdt: The SDT whose length is to be updated.
52162306a36Sopenharmony_ci *
52262306a36Sopenharmony_ci * This will traverse the table and accumulate the length of its components,
52362306a36Sopenharmony_ci * which is then used to replace the 'section_length' field.
52462306a36Sopenharmony_ci *
52562306a36Sopenharmony_ci * If section_length > MAX_SECTION_LEN, the operation fails.
52662306a36Sopenharmony_ci */
52762306a36Sopenharmony_civoid vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci/**
53062306a36Sopenharmony_ci * struct vidtv_psi_pat_write_args - Arguments for writing a PAT table
53162306a36Sopenharmony_ci * @buf: The destination buffer.
53262306a36Sopenharmony_ci * @offset: The offset into the destination buffer.
53362306a36Sopenharmony_ci * @pat: A pointer to the PAT.
53462306a36Sopenharmony_ci * @buf_sz: The size of the destination buffer.
53562306a36Sopenharmony_ci * @continuity_counter: A pointer to the CC. Incremented on every new packet.
53662306a36Sopenharmony_ci *
53762306a36Sopenharmony_ci */
53862306a36Sopenharmony_cistruct vidtv_psi_pat_write_args {
53962306a36Sopenharmony_ci	char *buf;
54062306a36Sopenharmony_ci	u32 offset;
54162306a36Sopenharmony_ci	struct vidtv_psi_table_pat *pat;
54262306a36Sopenharmony_ci	u32 buf_sz;
54362306a36Sopenharmony_ci	u8 *continuity_counter;
54462306a36Sopenharmony_ci};
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci/**
54762306a36Sopenharmony_ci * vidtv_psi_pat_write_into - Write PAT as MPEG-TS packets into a buffer.
54862306a36Sopenharmony_ci * @args: An instance of struct vidtv_psi_pat_write_args
54962306a36Sopenharmony_ci *
55062306a36Sopenharmony_ci * This function writes the MPEG TS packets for a PAT table into a buffer.
55162306a36Sopenharmony_ci * Calling code will usually generate the PAT via a call to its init function
55262306a36Sopenharmony_ci * and thus is responsible for freeing it.
55362306a36Sopenharmony_ci *
55462306a36Sopenharmony_ci * Return: The number of bytes written into the buffer. This is NOT
55562306a36Sopenharmony_ci * equal to the size of the PAT, since more space is needed for TS headers during TS
55662306a36Sopenharmony_ci * encapsulation.
55762306a36Sopenharmony_ci */
55862306a36Sopenharmony_ciu32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args);
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci/**
56162306a36Sopenharmony_ci * struct vidtv_psi_sdt_write_args - Arguments for writing a SDT table
56262306a36Sopenharmony_ci * @buf: The destination buffer.
56362306a36Sopenharmony_ci * @offset: The offset into the destination buffer.
56462306a36Sopenharmony_ci * @sdt: A pointer to the SDT.
56562306a36Sopenharmony_ci * @buf_sz: The size of the destination buffer.
56662306a36Sopenharmony_ci * @continuity_counter: A pointer to the CC. Incremented on every new packet.
56762306a36Sopenharmony_ci *
56862306a36Sopenharmony_ci */
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_cistruct vidtv_psi_sdt_write_args {
57162306a36Sopenharmony_ci	char *buf;
57262306a36Sopenharmony_ci	u32 offset;
57362306a36Sopenharmony_ci	struct vidtv_psi_table_sdt *sdt;
57462306a36Sopenharmony_ci	u32 buf_sz;
57562306a36Sopenharmony_ci	u8 *continuity_counter;
57662306a36Sopenharmony_ci};
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci/**
57962306a36Sopenharmony_ci * vidtv_psi_sdt_write_into - Write SDT as MPEG-TS packets into a buffer.
58062306a36Sopenharmony_ci * @args: an instance of struct vidtv_psi_sdt_write_args
58162306a36Sopenharmony_ci *
58262306a36Sopenharmony_ci * This function writes the MPEG TS packets for a SDT table into a buffer.
58362306a36Sopenharmony_ci * Calling code will usually generate the SDT via a call to its init function
58462306a36Sopenharmony_ci * and thus is responsible for freeing it.
58562306a36Sopenharmony_ci *
58662306a36Sopenharmony_ci * Return: The number of bytes written into the buffer. This is NOT
58762306a36Sopenharmony_ci * equal to the size of the SDT, since more space is needed for TS headers during TS
58862306a36Sopenharmony_ci * encapsulation.
58962306a36Sopenharmony_ci */
59062306a36Sopenharmony_ciu32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args);
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci/**
59362306a36Sopenharmony_ci * struct vidtv_psi_pmt_write_args - Arguments for writing a PMT section
59462306a36Sopenharmony_ci * @buf: The destination buffer.
59562306a36Sopenharmony_ci * @offset: The offset into the destination buffer.
59662306a36Sopenharmony_ci * @pmt: A pointer to the PMT.
59762306a36Sopenharmony_ci * @pid: Program ID
59862306a36Sopenharmony_ci * @buf_sz: The size of the destination buffer.
59962306a36Sopenharmony_ci * @continuity_counter: A pointer to the CC. Incremented on every new packet.
60062306a36Sopenharmony_ci * @pcr_pid: The TS PID used for the PSI packets. All channels will share the
60162306a36Sopenharmony_ci * same PCR.
60262306a36Sopenharmony_ci */
60362306a36Sopenharmony_cistruct vidtv_psi_pmt_write_args {
60462306a36Sopenharmony_ci	char *buf;
60562306a36Sopenharmony_ci	u32 offset;
60662306a36Sopenharmony_ci	struct vidtv_psi_table_pmt *pmt;
60762306a36Sopenharmony_ci	u16 pid;
60862306a36Sopenharmony_ci	u32 buf_sz;
60962306a36Sopenharmony_ci	u8 *continuity_counter;
61062306a36Sopenharmony_ci	u16 pcr_pid;
61162306a36Sopenharmony_ci};
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci/**
61462306a36Sopenharmony_ci * vidtv_psi_pmt_write_into - Write PMT as MPEG-TS packets into a buffer.
61562306a36Sopenharmony_ci * @args: an instance of struct vidtv_psi_pmt_write_args
61662306a36Sopenharmony_ci *
61762306a36Sopenharmony_ci * This function writes the MPEG TS packets for a PMT section into a buffer.
61862306a36Sopenharmony_ci * Calling code will usually generate the PMT section via a call to its init function
61962306a36Sopenharmony_ci * and thus is responsible for freeing it.
62062306a36Sopenharmony_ci *
62162306a36Sopenharmony_ci * Return: The number of bytes written into the buffer. This is NOT
62262306a36Sopenharmony_ci * equal to the size of the PMT section, since more space is needed for TS headers
62362306a36Sopenharmony_ci * during TS encapsulation.
62462306a36Sopenharmony_ci */
62562306a36Sopenharmony_ciu32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci/**
62862306a36Sopenharmony_ci * vidtv_psi_find_pmt_sec - Finds the PMT section for 'program_num'
62962306a36Sopenharmony_ci * @pmt_sections: The sections to look into.
63062306a36Sopenharmony_ci * @nsections: The number of sections.
63162306a36Sopenharmony_ci * @program_num: The 'program_num' from PAT pointing to a PMT section.
63262306a36Sopenharmony_ci *
63362306a36Sopenharmony_ci * Return: A pointer to the PMT, if found, or NULL.
63462306a36Sopenharmony_ci */
63562306a36Sopenharmony_cistruct vidtv_psi_table_pmt *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections,
63662306a36Sopenharmony_ci						   u16 nsections,
63762306a36Sopenharmony_ci						   u16 program_num);
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ciu16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p);
64062306a36Sopenharmony_ciu16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s);
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci/**
64362306a36Sopenharmony_ci * struct vidtv_psi_table_transport - A entry in the TS loop for the NIT and/or other tables.
64462306a36Sopenharmony_ci * See ETSI 300 468 section 5.2.1
64562306a36Sopenharmony_ci * @transport_id: The TS ID being described
64662306a36Sopenharmony_ci * @network_id: The network_id that contains the TS ID
64762306a36Sopenharmony_ci * @bitfield: Contains the descriptor loop length
64862306a36Sopenharmony_ci * @descriptor: A descriptor loop
64962306a36Sopenharmony_ci * @next: Pointer to the next entry
65062306a36Sopenharmony_ci *
65162306a36Sopenharmony_ci */
65262306a36Sopenharmony_cistruct vidtv_psi_table_transport {
65362306a36Sopenharmony_ci	__be16 transport_id;
65462306a36Sopenharmony_ci	__be16 network_id;
65562306a36Sopenharmony_ci	__be16 bitfield; /* desc_len: 12, reserved: 4 */
65662306a36Sopenharmony_ci	struct vidtv_psi_desc *descriptor;
65762306a36Sopenharmony_ci	struct vidtv_psi_table_transport *next;
65862306a36Sopenharmony_ci} __packed;
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci/**
66162306a36Sopenharmony_ci * struct vidtv_psi_table_nit - A Network Information Table (NIT). See ETSI 300
66262306a36Sopenharmony_ci * 468 section 5.2.1
66362306a36Sopenharmony_ci * @header: A PSI table header
66462306a36Sopenharmony_ci * @bitfield: Contains the network descriptor length
66562306a36Sopenharmony_ci * @descriptor: A descriptor loop describing the network
66662306a36Sopenharmony_ci * @bitfield2: Contains the transport stream loop length
66762306a36Sopenharmony_ci * @transport: The transport stream loop
66862306a36Sopenharmony_ci *
66962306a36Sopenharmony_ci */
67062306a36Sopenharmony_cistruct vidtv_psi_table_nit {
67162306a36Sopenharmony_ci	struct vidtv_psi_table_header header;
67262306a36Sopenharmony_ci	__be16 bitfield; /* network_desc_len: 12, reserved:4 */
67362306a36Sopenharmony_ci	struct vidtv_psi_desc *descriptor;
67462306a36Sopenharmony_ci	__be16 bitfield2; /* ts_loop_len: 12, reserved: 4 */
67562306a36Sopenharmony_ci	struct vidtv_psi_table_transport *transport;
67662306a36Sopenharmony_ci} __packed;
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_cistruct vidtv_psi_table_nit
67962306a36Sopenharmony_ci*vidtv_psi_nit_table_init(u16 network_id,
68062306a36Sopenharmony_ci			  u16 transport_stream_id,
68162306a36Sopenharmony_ci			  char *network_name,
68262306a36Sopenharmony_ci			  struct vidtv_psi_desc_service_list_entry *service_list);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci/**
68562306a36Sopenharmony_ci * struct vidtv_psi_nit_write_args - Arguments for writing a NIT section
68662306a36Sopenharmony_ci * @buf: The destination buffer.
68762306a36Sopenharmony_ci * @offset: The offset into the destination buffer.
68862306a36Sopenharmony_ci * @nit: A pointer to the NIT
68962306a36Sopenharmony_ci * @buf_sz: The size of the destination buffer.
69062306a36Sopenharmony_ci * @continuity_counter: A pointer to the CC. Incremented on every new packet.
69162306a36Sopenharmony_ci *
69262306a36Sopenharmony_ci */
69362306a36Sopenharmony_cistruct vidtv_psi_nit_write_args {
69462306a36Sopenharmony_ci	char *buf;
69562306a36Sopenharmony_ci	u32 offset;
69662306a36Sopenharmony_ci	struct vidtv_psi_table_nit *nit;
69762306a36Sopenharmony_ci	u32 buf_sz;
69862306a36Sopenharmony_ci	u8 *continuity_counter;
69962306a36Sopenharmony_ci};
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci/**
70262306a36Sopenharmony_ci * vidtv_psi_nit_write_into - Write NIT as MPEG-TS packets into a buffer.
70362306a36Sopenharmony_ci * @args: an instance of struct vidtv_psi_nit_write_args
70462306a36Sopenharmony_ci *
70562306a36Sopenharmony_ci * This function writes the MPEG TS packets for a NIT table into a buffer.
70662306a36Sopenharmony_ci * Calling code will usually generate the NIT via a call to its init function
70762306a36Sopenharmony_ci * and thus is responsible for freeing it.
70862306a36Sopenharmony_ci *
70962306a36Sopenharmony_ci * Return: The number of bytes written into the buffer. This is NOT
71062306a36Sopenharmony_ci * equal to the size of the NIT, since more space is needed for TS headers during TS
71162306a36Sopenharmony_ci * encapsulation.
71262306a36Sopenharmony_ci */
71362306a36Sopenharmony_ciu32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args);
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_civoid vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit);
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci/*
71862306a36Sopenharmony_ci * struct vidtv_psi_desc_short_event - A short event descriptor
71962306a36Sopenharmony_ci * see ETSI EN 300 468 v1.15.1 section 6.2.37
72062306a36Sopenharmony_ci */
72162306a36Sopenharmony_cistruct vidtv_psi_table_eit_event {
72262306a36Sopenharmony_ci	__be16 event_id;
72362306a36Sopenharmony_ci	u8 start_time[5];
72462306a36Sopenharmony_ci	u8 duration[3];
72562306a36Sopenharmony_ci	__be16 bitfield; /* desc_length: 12, free_CA_mode: 1, running_status: 1 */
72662306a36Sopenharmony_ci	struct vidtv_psi_desc *descriptor;
72762306a36Sopenharmony_ci	struct vidtv_psi_table_eit_event *next;
72862306a36Sopenharmony_ci} __packed;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci/*
73162306a36Sopenharmony_ci * struct vidtv_psi_table_eit - A Event Information Table (EIT)
73262306a36Sopenharmony_ci * See ETSI 300 468 section 5.2.4
73362306a36Sopenharmony_ci */
73462306a36Sopenharmony_cistruct vidtv_psi_table_eit {
73562306a36Sopenharmony_ci	struct vidtv_psi_table_header header;
73662306a36Sopenharmony_ci	__be16 transport_id;
73762306a36Sopenharmony_ci	__be16 network_id;
73862306a36Sopenharmony_ci	u8 last_segment;
73962306a36Sopenharmony_ci	u8 last_table_id;
74062306a36Sopenharmony_ci	struct vidtv_psi_table_eit_event *event;
74162306a36Sopenharmony_ci} __packed;
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_cistruct vidtv_psi_table_eit
74462306a36Sopenharmony_ci*vidtv_psi_eit_table_init(u16 network_id,
74562306a36Sopenharmony_ci			  u16 transport_stream_id,
74662306a36Sopenharmony_ci			  __be16 service_id);
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci/**
74962306a36Sopenharmony_ci * struct vidtv_psi_eit_write_args - Arguments for writing an EIT section
75062306a36Sopenharmony_ci * @buf: The destination buffer.
75162306a36Sopenharmony_ci * @offset: The offset into the destination buffer.
75262306a36Sopenharmony_ci * @eit: A pointer to the EIT
75362306a36Sopenharmony_ci * @buf_sz: The size of the destination buffer.
75462306a36Sopenharmony_ci * @continuity_counter: A pointer to the CC. Incremented on every new packet.
75562306a36Sopenharmony_ci *
75662306a36Sopenharmony_ci */
75762306a36Sopenharmony_cistruct vidtv_psi_eit_write_args {
75862306a36Sopenharmony_ci	char *buf;
75962306a36Sopenharmony_ci	u32 offset;
76062306a36Sopenharmony_ci	struct vidtv_psi_table_eit *eit;
76162306a36Sopenharmony_ci	u32 buf_sz;
76262306a36Sopenharmony_ci	u8 *continuity_counter;
76362306a36Sopenharmony_ci};
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci/**
76662306a36Sopenharmony_ci * vidtv_psi_eit_write_into - Write EIT as MPEG-TS packets into a buffer.
76762306a36Sopenharmony_ci * @args: an instance of struct vidtv_psi_nit_write_args
76862306a36Sopenharmony_ci *
76962306a36Sopenharmony_ci * This function writes the MPEG TS packets for a EIT table into a buffer.
77062306a36Sopenharmony_ci * Calling code will usually generate the EIT via a call to its init function
77162306a36Sopenharmony_ci * and thus is responsible for freeing it.
77262306a36Sopenharmony_ci *
77362306a36Sopenharmony_ci * Return: The number of bytes written into the buffer. This is NOT
77462306a36Sopenharmony_ci * equal to the size of the EIT, since more space is needed for TS headers during TS
77562306a36Sopenharmony_ci * encapsulation.
77662306a36Sopenharmony_ci */
77762306a36Sopenharmony_ciu32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args);
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_civoid vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit);
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci/**
78262306a36Sopenharmony_ci * vidtv_psi_eit_table_update_sec_len - Recompute and update the EIT section length.
78362306a36Sopenharmony_ci * @eit: The EIT whose length is to be updated.
78462306a36Sopenharmony_ci *
78562306a36Sopenharmony_ci * This will traverse the table and accumulate the length of its components,
78662306a36Sopenharmony_ci * which is then used to replace the 'section_length' field.
78762306a36Sopenharmony_ci *
78862306a36Sopenharmony_ci * If section_length > EIT_MAX_SECTION_LEN, the operation fails.
78962306a36Sopenharmony_ci */
79062306a36Sopenharmony_civoid vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit);
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci/**
79362306a36Sopenharmony_ci * vidtv_psi_eit_event_assign - Assigns the event loop to the EIT.
79462306a36Sopenharmony_ci * @eit: The EIT to assign to.
79562306a36Sopenharmony_ci * @e: The event loop
79662306a36Sopenharmony_ci *
79762306a36Sopenharmony_ci * This will free the previous event loop in the table.
79862306a36Sopenharmony_ci * This will assign ownership of the stream loop to the table, i.e. the table
79962306a36Sopenharmony_ci * will free this stream loop when a call to its destroy function is made.
80062306a36Sopenharmony_ci */
80162306a36Sopenharmony_civoid vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit,
80262306a36Sopenharmony_ci				struct vidtv_psi_table_eit_event *e);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_cistruct vidtv_psi_table_eit_event
80562306a36Sopenharmony_ci*vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id);
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_civoid vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e);
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci#endif // VIDTV_PSI_H
810