Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * This file contains the logic to work with MPEG Program-Specific Information.
0004  * These are defined both in ISO/IEC 13818-1 (systems) and ETSI EN 300 468.
0005  * PSI is carried in the form of table structures, and although each table might
0006  * technically be broken into one or more sections, we do not do this here,
0007  * hence 'table' and 'section' are interchangeable for vidtv.
0008  *
0009  * Copyright (C) 2020 Daniel W. S. Almeida
0010  */
0011 
0012 #define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
0013 
0014 #include <linux/bcd.h>
0015 #include <linux/crc32.h>
0016 #include <linux/kernel.h>
0017 #include <linux/ktime.h>
0018 #include <linux/printk.h>
0019 #include <linux/ratelimit.h>
0020 #include <linux/slab.h>
0021 #include <linux/string.h>
0022 #include <linux/time.h>
0023 #include <linux/types.h>
0024 
0025 #include "vidtv_common.h"
0026 #include "vidtv_psi.h"
0027 #include "vidtv_ts.h"
0028 
0029 #define CRC_SIZE_IN_BYTES 4
0030 #define MAX_VERSION_NUM 32
0031 #define INITIAL_CRC 0xffffffff
0032 #define ISO_LANGUAGE_CODE_LEN 3
0033 
0034 static const u32 CRC_LUT[256] = {
0035     /* from libdvbv5 */
0036     0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0037     0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0038     0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
0039     0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0040     0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
0041     0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0042     0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
0043     0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0044     0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
0045     0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0046     0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0047     0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0048     0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
0049     0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0050     0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
0051     0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0052     0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
0053     0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0054     0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
0055     0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0056     0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
0057     0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0058     0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
0059     0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0060     0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
0061     0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0062     0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
0063     0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0064     0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
0065     0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0066     0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0067     0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0068     0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
0069     0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0070     0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
0071     0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0072     0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
0073     0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0074     0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
0075     0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0076     0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0077     0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0078     0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
0079 };
0080 
0081 static u32 dvb_crc32(u32 crc, u8 *data, u32 len)
0082 {
0083     /* from libdvbv5 */
0084     while (len--)
0085         crc = (crc << 8) ^ CRC_LUT[((crc >> 24) ^ *data++) & 0xff];
0086     return crc;
0087 }
0088 
0089 static void vidtv_psi_update_version_num(struct vidtv_psi_table_header *h)
0090 {
0091     h->version++;
0092 }
0093 
0094 static u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h)
0095 {
0096     u16 mask;
0097 
0098     mask = GENMASK(11, 0);
0099 
0100     return be16_to_cpu(h->bitfield) & mask;
0101 }
0102 
0103 u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p)
0104 {
0105     u16 mask;
0106 
0107     mask = GENMASK(12, 0);
0108 
0109     return be16_to_cpu(p->bitfield) & mask;
0110 }
0111 
0112 u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s)
0113 {
0114     u16 mask;
0115 
0116     mask = GENMASK(12, 0);
0117 
0118     return be16_to_cpu(s->bitfield) & mask;
0119 }
0120 
0121 static void vidtv_psi_set_desc_loop_len(__be16 *bitfield, u16 new_len,
0122                     u8 desc_len_nbits)
0123 {
0124     __be16 new;
0125     u16 mask;
0126 
0127     mask = GENMASK(15, desc_len_nbits);
0128 
0129     new = cpu_to_be16((be16_to_cpu(*bitfield) & mask) | new_len);
0130     *bitfield = new;
0131 }
0132 
0133 static void vidtv_psi_set_sec_len(struct vidtv_psi_table_header *h, u16 new_len)
0134 {
0135     u16 old_len = vidtv_psi_get_sec_len(h);
0136     __be16 new;
0137     u16 mask;
0138 
0139     mask = GENMASK(15, 13);
0140 
0141     new = cpu_to_be16((be16_to_cpu(h->bitfield) & mask) | new_len);
0142 
0143     if (old_len > MAX_SECTION_LEN)
0144         pr_warn_ratelimited("section length: %d > %d, old len was %d\n",
0145                     new_len,
0146                     MAX_SECTION_LEN,
0147                     old_len);
0148 
0149     h->bitfield = new;
0150 }
0151 
0152 /*
0153  * Packetize PSI sections into TS packets:
0154  * push a TS header (4bytes) every 184 bytes
0155  * manage the continuity_counter
0156  * add stuffing (i.e. padding bytes) after the CRC
0157  */
0158 static u32 vidtv_psi_ts_psi_write_into(struct psi_write_args *args)
0159 {
0160     struct vidtv_mpeg_ts ts_header = {
0161         .sync_byte = TS_SYNC_BYTE,
0162         .bitfield = cpu_to_be16((args->new_psi_section << 14) | args->pid),
0163         .scrambling = 0,
0164         .payload = 1,
0165         .adaptation_field = 0, /* no adaptation field */
0166     };
0167     u32 nbytes_past_boundary = (args->dest_offset % TS_PACKET_LEN);
0168     bool aligned = (nbytes_past_boundary == 0);
0169     u32 remaining_len = args->len;
0170     u32 payload_write_len = 0;
0171     u32 payload_offset = 0;
0172     u32 nbytes = 0;
0173 
0174     if (!args->crc && !args->is_crc)
0175         pr_warn_ratelimited("Missing CRC for chunk\n");
0176 
0177     if (args->crc)
0178         *args->crc = dvb_crc32(*args->crc, args->from, args->len);
0179 
0180     if (args->new_psi_section && !aligned) {
0181         pr_warn_ratelimited("Cannot write a new PSI section in a misaligned buffer\n");
0182 
0183         /* forcibly align and hope for the best */
0184         nbytes += vidtv_memset(args->dest_buf,
0185                        args->dest_offset + nbytes,
0186                        args->dest_buf_sz,
0187                        TS_FILL_BYTE,
0188                        TS_PACKET_LEN - nbytes_past_boundary);
0189     }
0190 
0191     while (remaining_len) {
0192         nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN;
0193         aligned = (nbytes_past_boundary == 0);
0194 
0195         if (aligned) {
0196             /* if at a packet boundary, write a new TS header */
0197             ts_header.continuity_counter = *args->continuity_counter;
0198 
0199             nbytes += vidtv_memcpy(args->dest_buf,
0200                            args->dest_offset + nbytes,
0201                            args->dest_buf_sz,
0202                            &ts_header,
0203                            sizeof(ts_header));
0204             /*
0205              * This will trigger a discontinuity if the buffer is full,
0206              * effectively dropping the packet.
0207              */
0208             vidtv_ts_inc_cc(args->continuity_counter);
0209         }
0210 
0211         /* write the pointer_field in the first byte of the payload */
0212         if (args->new_psi_section)
0213             nbytes += vidtv_memset(args->dest_buf,
0214                            args->dest_offset + nbytes,
0215                            args->dest_buf_sz,
0216                            0x0,
0217                            1);
0218 
0219         /* write as much of the payload as possible */
0220         nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN;
0221         payload_write_len = min(TS_PACKET_LEN - nbytes_past_boundary, remaining_len);
0222 
0223         nbytes += vidtv_memcpy(args->dest_buf,
0224                        args->dest_offset + nbytes,
0225                        args->dest_buf_sz,
0226                        args->from + payload_offset,
0227                        payload_write_len);
0228 
0229         /* 'payload_write_len' written from a total of 'len' requested*/
0230         remaining_len -= payload_write_len;
0231         payload_offset += payload_write_len;
0232     }
0233 
0234     /*
0235      * fill the rest of the packet if there is any remaining space unused
0236      */
0237 
0238     nbytes_past_boundary = (args->dest_offset + nbytes) % TS_PACKET_LEN;
0239 
0240     if (args->is_crc)
0241         nbytes += vidtv_memset(args->dest_buf,
0242                        args->dest_offset + nbytes,
0243                        args->dest_buf_sz,
0244                        TS_FILL_BYTE,
0245                        TS_PACKET_LEN - nbytes_past_boundary);
0246 
0247     return nbytes;
0248 }
0249 
0250 static u32 table_section_crc32_write_into(struct crc32_write_args *args)
0251 {
0252     struct psi_write_args psi_args = {
0253         .dest_buf           = args->dest_buf,
0254         .from               = &args->crc,
0255         .len                = CRC_SIZE_IN_BYTES,
0256         .dest_offset        = args->dest_offset,
0257         .pid                = args->pid,
0258         .new_psi_section    = false,
0259         .continuity_counter = args->continuity_counter,
0260         .is_crc             = true,
0261         .dest_buf_sz        = args->dest_buf_sz,
0262     };
0263 
0264     /* the CRC is the last entry in the section */
0265 
0266     return vidtv_psi_ts_psi_write_into(&psi_args);
0267 }
0268 
0269 static void vidtv_psi_desc_chain(struct vidtv_psi_desc *head, struct vidtv_psi_desc *desc)
0270 {
0271     if (head) {
0272         while (head->next)
0273             head = head->next;
0274 
0275         head->next = desc;
0276     }
0277 }
0278 
0279 struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc *head,
0280                                enum service_type service_type,
0281                                char *service_name,
0282                                char *provider_name)
0283 {
0284     struct vidtv_psi_desc_service *desc;
0285     u32 service_name_len = service_name ? strlen(service_name) : 0;
0286     u32 provider_name_len = provider_name ? strlen(provider_name) : 0;
0287 
0288     desc = kzalloc(sizeof(*desc), GFP_KERNEL);
0289     if (!desc)
0290         return NULL;
0291 
0292     desc->type = SERVICE_DESCRIPTOR;
0293 
0294     desc->length = sizeof_field(struct vidtv_psi_desc_service, service_type)
0295                + sizeof_field(struct vidtv_psi_desc_service, provider_name_len)
0296                + provider_name_len
0297                + sizeof_field(struct vidtv_psi_desc_service, service_name_len)
0298                + service_name_len;
0299 
0300     desc->service_type = service_type;
0301 
0302     desc->service_name_len = service_name_len;
0303 
0304     if (service_name && service_name_len)
0305         desc->service_name = kstrdup(service_name, GFP_KERNEL);
0306 
0307     desc->provider_name_len = provider_name_len;
0308 
0309     if (provider_name && provider_name_len)
0310         desc->provider_name = kstrdup(provider_name, GFP_KERNEL);
0311 
0312     vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
0313     return desc;
0314 }
0315 
0316 struct vidtv_psi_desc_registration
0317 *vidtv_psi_registration_desc_init(struct vidtv_psi_desc *head,
0318                   __be32 format_id,
0319                   u8 *additional_ident_info,
0320                   u32 additional_info_len)
0321 {
0322     struct vidtv_psi_desc_registration *desc;
0323 
0324     desc = kzalloc(sizeof(*desc) + sizeof(format_id) + additional_info_len, GFP_KERNEL);
0325     if (!desc)
0326         return NULL;
0327 
0328     desc->type = REGISTRATION_DESCRIPTOR;
0329 
0330     desc->length = sizeof_field(struct vidtv_psi_desc_registration, format_id)
0331                + additional_info_len;
0332 
0333     desc->format_id = format_id;
0334 
0335     if (additional_ident_info && additional_info_len)
0336         memcpy(desc->additional_identification_info,
0337                additional_ident_info,
0338                additional_info_len);
0339 
0340     vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
0341     return desc;
0342 }
0343 
0344 struct vidtv_psi_desc_network_name
0345 *vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name)
0346 {
0347     u32 network_name_len = network_name ? strlen(network_name) : 0;
0348     struct vidtv_psi_desc_network_name *desc;
0349 
0350     desc = kzalloc(sizeof(*desc), GFP_KERNEL);
0351     if (!desc)
0352         return NULL;
0353 
0354     desc->type = NETWORK_NAME_DESCRIPTOR;
0355 
0356     desc->length = network_name_len;
0357 
0358     if (network_name && network_name_len)
0359         desc->network_name = kstrdup(network_name, GFP_KERNEL);
0360 
0361     vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
0362     return desc;
0363 }
0364 
0365 struct vidtv_psi_desc_service_list
0366 *vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head,
0367                   struct vidtv_psi_desc_service_list_entry *entry)
0368 {
0369     struct vidtv_psi_desc_service_list_entry *curr_e = NULL;
0370     struct vidtv_psi_desc_service_list_entry *head_e = NULL;
0371     struct vidtv_psi_desc_service_list_entry *prev_e = NULL;
0372     struct vidtv_psi_desc_service_list *desc;
0373     u16 length = 0;
0374 
0375     desc = kzalloc(sizeof(*desc), GFP_KERNEL);
0376     if (!desc)
0377         return NULL;
0378 
0379     desc->type = SERVICE_LIST_DESCRIPTOR;
0380 
0381     while (entry) {
0382         curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL);
0383         if (!curr_e) {
0384             while (head_e) {
0385                 curr_e = head_e;
0386                 head_e = head_e->next;
0387                 kfree(curr_e);
0388             }
0389             kfree(desc);
0390             return NULL;
0391         }
0392 
0393         curr_e->service_id = entry->service_id;
0394         curr_e->service_type = entry->service_type;
0395 
0396         length += sizeof(struct vidtv_psi_desc_service_list_entry) -
0397               sizeof(struct vidtv_psi_desc_service_list_entry *);
0398 
0399         if (!head_e)
0400             head_e = curr_e;
0401         if (prev_e)
0402             prev_e->next = curr_e;
0403 
0404         prev_e = curr_e;
0405         entry = entry->next;
0406     }
0407 
0408     desc->length = length;
0409     desc->service_list = head_e;
0410 
0411     vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
0412     return desc;
0413 }
0414 
0415 struct vidtv_psi_desc_short_event
0416 *vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head,
0417                  char *iso_language_code,
0418                  char *event_name,
0419                  char *text)
0420 {
0421     u32 iso_len =  iso_language_code ? strlen(iso_language_code) : 0;
0422     u32 event_name_len = event_name ? strlen(event_name) : 0;
0423     struct vidtv_psi_desc_short_event *desc;
0424     u32 text_len =  text ? strlen(text) : 0;
0425 
0426     desc = kzalloc(sizeof(*desc), GFP_KERNEL);
0427     if (!desc)
0428         return NULL;
0429 
0430     desc->type = SHORT_EVENT_DESCRIPTOR;
0431 
0432     desc->length = ISO_LANGUAGE_CODE_LEN +
0433                sizeof_field(struct vidtv_psi_desc_short_event, event_name_len) +
0434                event_name_len +
0435                sizeof_field(struct vidtv_psi_desc_short_event, text_len) +
0436                text_len;
0437 
0438     desc->event_name_len = event_name_len;
0439     desc->text_len = text_len;
0440 
0441     if (iso_len != ISO_LANGUAGE_CODE_LEN)
0442         iso_language_code = "eng";
0443 
0444     desc->iso_language_code = kstrdup(iso_language_code, GFP_KERNEL);
0445 
0446     if (event_name && event_name_len)
0447         desc->event_name = kstrdup(event_name, GFP_KERNEL);
0448 
0449     if (text && text_len)
0450         desc->text = kstrdup(text, GFP_KERNEL);
0451 
0452     vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
0453     return desc;
0454 }
0455 
0456 struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc)
0457 {
0458     struct vidtv_psi_desc_network_name *desc_network_name;
0459     struct vidtv_psi_desc_service_list *desc_service_list;
0460     struct vidtv_psi_desc_short_event  *desc_short_event;
0461     struct vidtv_psi_desc_service *service;
0462     struct vidtv_psi_desc *head = NULL;
0463     struct vidtv_psi_desc *prev = NULL;
0464     struct vidtv_psi_desc *curr = NULL;
0465 
0466     while (desc) {
0467         switch (desc->type) {
0468         case SERVICE_DESCRIPTOR:
0469             service = (struct vidtv_psi_desc_service *)desc;
0470             curr = (struct vidtv_psi_desc *)
0471                    vidtv_psi_service_desc_init(head,
0472                                service->service_type,
0473                                service->service_name,
0474                                service->provider_name);
0475         break;
0476 
0477         case NETWORK_NAME_DESCRIPTOR:
0478             desc_network_name = (struct vidtv_psi_desc_network_name *)desc;
0479             curr = (struct vidtv_psi_desc *)
0480                    vidtv_psi_network_name_desc_init(head,
0481                                 desc_network_name->network_name);
0482         break;
0483 
0484         case SERVICE_LIST_DESCRIPTOR:
0485             desc_service_list = (struct vidtv_psi_desc_service_list *)desc;
0486             curr = (struct vidtv_psi_desc *)
0487                    vidtv_psi_service_list_desc_init(head,
0488                                 desc_service_list->service_list);
0489         break;
0490 
0491         case SHORT_EVENT_DESCRIPTOR:
0492             desc_short_event = (struct vidtv_psi_desc_short_event *)desc;
0493             curr = (struct vidtv_psi_desc *)
0494                    vidtv_psi_short_event_desc_init(head,
0495                                    desc_short_event->iso_language_code,
0496                                    desc_short_event->event_name,
0497                                    desc_short_event->text);
0498         break;
0499 
0500         case REGISTRATION_DESCRIPTOR:
0501         default:
0502             curr = kmemdup(desc, sizeof(*desc) + desc->length, GFP_KERNEL);
0503             if (!curr)
0504                 return NULL;
0505         }
0506 
0507         if (!curr)
0508             return NULL;
0509 
0510         curr->next = NULL;
0511         if (!head)
0512             head = curr;
0513         if (prev)
0514             prev->next = curr;
0515 
0516         prev = curr;
0517         desc = desc->next;
0518     }
0519 
0520     return head;
0521 }
0522 
0523 void vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc)
0524 {
0525     struct vidtv_psi_desc_service_list_entry *sl_entry_tmp = NULL;
0526     struct vidtv_psi_desc_service_list_entry *sl_entry = NULL;
0527     struct vidtv_psi_desc *curr = desc;
0528     struct vidtv_psi_desc *tmp  = NULL;
0529 
0530     while (curr) {
0531         tmp  = curr;
0532         curr = curr->next;
0533 
0534         switch (tmp->type) {
0535         case SERVICE_DESCRIPTOR:
0536             kfree(((struct vidtv_psi_desc_service *)tmp)->provider_name);
0537             kfree(((struct vidtv_psi_desc_service *)tmp)->service_name);
0538 
0539             break;
0540         case REGISTRATION_DESCRIPTOR:
0541             /* nothing to do */
0542             break;
0543 
0544         case NETWORK_NAME_DESCRIPTOR:
0545             kfree(((struct vidtv_psi_desc_network_name *)tmp)->network_name);
0546             break;
0547 
0548         case SERVICE_LIST_DESCRIPTOR:
0549             sl_entry = ((struct vidtv_psi_desc_service_list *)tmp)->service_list;
0550             while (sl_entry) {
0551                 sl_entry_tmp = sl_entry;
0552                 sl_entry = sl_entry->next;
0553                 kfree(sl_entry_tmp);
0554             }
0555             break;
0556 
0557         case SHORT_EVENT_DESCRIPTOR:
0558             kfree(((struct vidtv_psi_desc_short_event *)tmp)->iso_language_code);
0559             kfree(((struct vidtv_psi_desc_short_event *)tmp)->event_name);
0560             kfree(((struct vidtv_psi_desc_short_event *)tmp)->text);
0561         break;
0562 
0563         default:
0564             pr_warn_ratelimited("Possible leak: not handling descriptor type %d\n",
0565                         tmp->type);
0566             break;
0567         }
0568 
0569         kfree(tmp);
0570     }
0571 }
0572 
0573 static u16
0574 vidtv_psi_desc_comp_loop_len(struct vidtv_psi_desc *desc)
0575 {
0576     u32 length = 0;
0577 
0578     if (!desc)
0579         return 0;
0580 
0581     while (desc) {
0582         length += sizeof_field(struct vidtv_psi_desc, type);
0583         length += sizeof_field(struct vidtv_psi_desc, length);
0584         length += desc->length; /* from 'length' field until the end of the descriptor */
0585         desc    = desc->next;
0586     }
0587 
0588     return length;
0589 }
0590 
0591 void vidtv_psi_desc_assign(struct vidtv_psi_desc **to,
0592                struct vidtv_psi_desc *desc)
0593 {
0594     if (desc == *to)
0595         return;
0596 
0597     if (*to)
0598         vidtv_psi_desc_destroy(*to);
0599 
0600     *to = desc;
0601 }
0602 
0603 void vidtv_pmt_desc_assign(struct vidtv_psi_table_pmt *pmt,
0604                struct vidtv_psi_desc **to,
0605                struct vidtv_psi_desc *desc)
0606 {
0607     vidtv_psi_desc_assign(to, desc);
0608     vidtv_psi_pmt_table_update_sec_len(pmt);
0609 
0610     if (vidtv_psi_get_sec_len(&pmt->header) > MAX_SECTION_LEN)
0611         vidtv_psi_desc_assign(to, NULL);
0612 
0613     vidtv_psi_update_version_num(&pmt->header);
0614 }
0615 
0616 void vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt,
0617                struct vidtv_psi_desc **to,
0618                struct vidtv_psi_desc *desc)
0619 {
0620     vidtv_psi_desc_assign(to, desc);
0621     vidtv_psi_sdt_table_update_sec_len(sdt);
0622 
0623     if (vidtv_psi_get_sec_len(&sdt->header) > MAX_SECTION_LEN)
0624         vidtv_psi_desc_assign(to, NULL);
0625 
0626     vidtv_psi_update_version_num(&sdt->header);
0627 }
0628 
0629 static u32 vidtv_psi_desc_write_into(struct desc_write_args *args)
0630 {
0631     struct psi_write_args psi_args = {
0632         .dest_buf           = args->dest_buf,
0633         .from               = &args->desc->type,
0634         .pid                = args->pid,
0635         .new_psi_section    = false,
0636         .continuity_counter = args->continuity_counter,
0637         .is_crc             = false,
0638         .dest_buf_sz        = args->dest_buf_sz,
0639         .crc                = args->crc,
0640         .len            = sizeof_field(struct vidtv_psi_desc, type) +
0641                       sizeof_field(struct vidtv_psi_desc, length),
0642     };
0643     struct vidtv_psi_desc_service_list_entry *serv_list_entry = NULL;
0644     u32 nbytes = 0;
0645 
0646     psi_args.dest_offset        = args->dest_offset + nbytes;
0647 
0648     nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0649 
0650     switch (args->desc->type) {
0651     case SERVICE_DESCRIPTOR:
0652         psi_args.dest_offset = args->dest_offset + nbytes;
0653         psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_type) +
0654                    sizeof_field(struct vidtv_psi_desc_service, provider_name_len);
0655         psi_args.from = &((struct vidtv_psi_desc_service *)args->desc)->service_type;
0656 
0657         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0658 
0659         psi_args.dest_offset = args->dest_offset + nbytes;
0660         psi_args.len = ((struct vidtv_psi_desc_service *)args->desc)->provider_name_len;
0661         psi_args.from = ((struct vidtv_psi_desc_service *)args->desc)->provider_name;
0662 
0663         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0664 
0665         psi_args.dest_offset = args->dest_offset + nbytes;
0666         psi_args.len = sizeof_field(struct vidtv_psi_desc_service, service_name_len);
0667         psi_args.from = &((struct vidtv_psi_desc_service *)args->desc)->service_name_len;
0668 
0669         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0670 
0671         psi_args.dest_offset = args->dest_offset + nbytes;
0672         psi_args.len = ((struct vidtv_psi_desc_service *)args->desc)->service_name_len;
0673         psi_args.from = ((struct vidtv_psi_desc_service *)args->desc)->service_name;
0674 
0675         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0676         break;
0677 
0678     case NETWORK_NAME_DESCRIPTOR:
0679         psi_args.dest_offset = args->dest_offset + nbytes;
0680         psi_args.len = args->desc->length;
0681         psi_args.from = ((struct vidtv_psi_desc_network_name *)args->desc)->network_name;
0682 
0683         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0684         break;
0685 
0686     case SERVICE_LIST_DESCRIPTOR:
0687         serv_list_entry = ((struct vidtv_psi_desc_service_list *)args->desc)->service_list;
0688         while (serv_list_entry) {
0689             psi_args.dest_offset = args->dest_offset + nbytes;
0690             psi_args.len = sizeof(struct vidtv_psi_desc_service_list_entry) -
0691                        sizeof(struct vidtv_psi_desc_service_list_entry *);
0692             psi_args.from = serv_list_entry;
0693 
0694             nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0695 
0696             serv_list_entry = serv_list_entry->next;
0697         }
0698         break;
0699 
0700     case SHORT_EVENT_DESCRIPTOR:
0701         psi_args.dest_offset = args->dest_offset + nbytes;
0702         psi_args.len = ISO_LANGUAGE_CODE_LEN;
0703         psi_args.from = ((struct vidtv_psi_desc_short_event *)
0704                   args->desc)->iso_language_code;
0705 
0706         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0707 
0708         psi_args.dest_offset = args->dest_offset + nbytes;
0709         psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, event_name_len);
0710         psi_args.from = &((struct vidtv_psi_desc_short_event *)
0711                   args->desc)->event_name_len;
0712 
0713         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0714 
0715         psi_args.dest_offset = args->dest_offset + nbytes;
0716         psi_args.len = ((struct vidtv_psi_desc_short_event *)args->desc)->event_name_len;
0717         psi_args.from = ((struct vidtv_psi_desc_short_event *)args->desc)->event_name;
0718 
0719         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0720 
0721         psi_args.dest_offset = args->dest_offset + nbytes;
0722         psi_args.len = sizeof_field(struct vidtv_psi_desc_short_event, text_len);
0723         psi_args.from = &((struct vidtv_psi_desc_short_event *)args->desc)->text_len;
0724 
0725         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0726 
0727         psi_args.dest_offset = args->dest_offset + nbytes;
0728         psi_args.len = ((struct vidtv_psi_desc_short_event *)args->desc)->text_len;
0729         psi_args.from = ((struct vidtv_psi_desc_short_event *)args->desc)->text;
0730 
0731         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0732 
0733         break;
0734 
0735     case REGISTRATION_DESCRIPTOR:
0736     default:
0737         psi_args.dest_offset = args->dest_offset + nbytes;
0738         psi_args.len = args->desc->length;
0739         psi_args.from = &args->desc->data;
0740 
0741         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
0742         break;
0743     }
0744 
0745     return nbytes;
0746 }
0747 
0748 static u32
0749 vidtv_psi_table_header_write_into(struct header_write_args *args)
0750 {
0751     struct psi_write_args psi_args = {
0752         .dest_buf           = args->dest_buf,
0753         .from               = args->h,
0754         .len                = sizeof(struct vidtv_psi_table_header),
0755         .dest_offset        = args->dest_offset,
0756         .pid                = args->pid,
0757         .new_psi_section    = true,
0758         .continuity_counter = args->continuity_counter,
0759         .is_crc             = false,
0760         .dest_buf_sz        = args->dest_buf_sz,
0761         .crc                = args->crc,
0762     };
0763 
0764     return vidtv_psi_ts_psi_write_into(&psi_args);
0765 }
0766 
0767 void
0768 vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat)
0769 {
0770     u16 length = 0;
0771     u32 i;
0772 
0773     /* see ISO/IEC 13818-1 : 2000 p.43 */
0774 
0775     /* from immediately after 'section_length' until 'last_section_number'*/
0776     length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER;
0777 
0778     /* do not count the pointer */
0779     for (i = 0; i < pat->num_pat; ++i)
0780         length += sizeof(struct vidtv_psi_table_pat_program) -
0781               sizeof(struct vidtv_psi_table_pat_program *);
0782 
0783     length += CRC_SIZE_IN_BYTES;
0784 
0785     vidtv_psi_set_sec_len(&pat->header, length);
0786 }
0787 
0788 void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt)
0789 {
0790     struct vidtv_psi_table_pmt_stream *s = pmt->stream;
0791     u16 desc_loop_len;
0792     u16 length = 0;
0793 
0794     /* see ISO/IEC 13818-1 : 2000 p.46 */
0795 
0796     /* from immediately after 'section_length' until 'program_info_length'*/
0797     length += PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH;
0798 
0799     desc_loop_len = vidtv_psi_desc_comp_loop_len(pmt->descriptor);
0800     vidtv_psi_set_desc_loop_len(&pmt->bitfield2, desc_loop_len, 10);
0801 
0802     length += desc_loop_len;
0803 
0804     while (s) {
0805         /* skip both pointers at the end */
0806         length += sizeof(struct vidtv_psi_table_pmt_stream) -
0807               sizeof(struct vidtv_psi_desc *) -
0808               sizeof(struct vidtv_psi_table_pmt_stream *);
0809 
0810         desc_loop_len = vidtv_psi_desc_comp_loop_len(s->descriptor);
0811         vidtv_psi_set_desc_loop_len(&s->bitfield2, desc_loop_len, 10);
0812 
0813         length += desc_loop_len;
0814 
0815         s = s->next;
0816     }
0817 
0818     length += CRC_SIZE_IN_BYTES;
0819 
0820     vidtv_psi_set_sec_len(&pmt->header, length);
0821 }
0822 
0823 void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt)
0824 {
0825     struct vidtv_psi_table_sdt_service *s = sdt->service;
0826     u16 desc_loop_len;
0827     u16 length = 0;
0828 
0829     /* see ETSI EN 300 468 V 1.10.1 p.24 */
0830 
0831     /*
0832      * from immediately after 'section_length' until
0833      * 'reserved_for_future_use'
0834      */
0835     length += SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE;
0836 
0837     while (s) {
0838         /* skip both pointers at the end */
0839         length += sizeof(struct vidtv_psi_table_sdt_service) -
0840               sizeof(struct vidtv_psi_desc *) -
0841               sizeof(struct vidtv_psi_table_sdt_service *);
0842 
0843         desc_loop_len = vidtv_psi_desc_comp_loop_len(s->descriptor);
0844         vidtv_psi_set_desc_loop_len(&s->bitfield, desc_loop_len, 12);
0845 
0846         length += desc_loop_len;
0847 
0848         s = s->next;
0849     }
0850 
0851     length += CRC_SIZE_IN_BYTES;
0852     vidtv_psi_set_sec_len(&sdt->header, length);
0853 }
0854 
0855 struct vidtv_psi_table_pat_program*
0856 vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head,
0857                u16 service_id,
0858                u16 program_map_pid)
0859 {
0860     struct vidtv_psi_table_pat_program *program;
0861     const u16 RESERVED = 0x07;
0862 
0863     program = kzalloc(sizeof(*program), GFP_KERNEL);
0864     if (!program)
0865         return NULL;
0866 
0867     program->service_id = cpu_to_be16(service_id);
0868 
0869     /* pid for the PMT section in the TS */
0870     program->bitfield = cpu_to_be16((RESERVED << 13) | program_map_pid);
0871     program->next = NULL;
0872 
0873     if (head) {
0874         while (head->next)
0875             head = head->next;
0876 
0877         head->next = program;
0878     }
0879 
0880     return program;
0881 }
0882 
0883 void
0884 vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p)
0885 {
0886     struct vidtv_psi_table_pat_program *tmp  = NULL;
0887     struct vidtv_psi_table_pat_program *curr = p;
0888 
0889     while (curr) {
0890         tmp  = curr;
0891         curr = curr->next;
0892         kfree(tmp);
0893     }
0894 }
0895 
0896 /* This function transfers ownership of p to the table */
0897 void
0898 vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat,
0899                  struct vidtv_psi_table_pat_program *p)
0900 {
0901     struct vidtv_psi_table_pat_program *program;
0902     u16 program_count;
0903 
0904     do {
0905         program_count = 0;
0906         program = p;
0907 
0908         if (p == pat->program)
0909             return;
0910 
0911         while (program) {
0912             ++program_count;
0913             program = program->next;
0914         }
0915 
0916         pat->num_pat = program_count;
0917         pat->program  = p;
0918 
0919         /* Recompute section length */
0920         vidtv_psi_pat_table_update_sec_len(pat);
0921 
0922         p = NULL;
0923     } while (vidtv_psi_get_sec_len(&pat->header) > MAX_SECTION_LEN);
0924 
0925     vidtv_psi_update_version_num(&pat->header);
0926 }
0927 
0928 struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id)
0929 {
0930     struct vidtv_psi_table_pat *pat;
0931     const u16 SYNTAX = 0x1;
0932     const u16 ZERO = 0x0;
0933     const u16 ONES = 0x03;
0934 
0935     pat = kzalloc(sizeof(*pat), GFP_KERNEL);
0936     if (!pat)
0937         return NULL;
0938 
0939     pat->header.table_id = 0x0;
0940 
0941     pat->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ZERO << 14) | (ONES << 12));
0942     pat->header.id           = cpu_to_be16(transport_stream_id);
0943     pat->header.current_next = 0x1;
0944 
0945     pat->header.version = 0x1f;
0946 
0947     pat->header.one2         = 0x03;
0948     pat->header.section_id   = 0x0;
0949     pat->header.last_section = 0x0;
0950 
0951     vidtv_psi_pat_table_update_sec_len(pat);
0952 
0953     return pat;
0954 }
0955 
0956 u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args)
0957 {
0958     struct vidtv_psi_table_pat_program *p = args->pat->program;
0959     struct header_write_args h_args       = {
0960         .dest_buf           = args->buf,
0961         .dest_offset        = args->offset,
0962         .pid                = VIDTV_PAT_PID,
0963         .h                  = &args->pat->header,
0964         .continuity_counter = args->continuity_counter,
0965         .dest_buf_sz        = args->buf_sz,
0966     };
0967     struct psi_write_args psi_args        = {
0968         .dest_buf           = args->buf,
0969         .pid                = VIDTV_PAT_PID,
0970         .new_psi_section    = false,
0971         .continuity_counter = args->continuity_counter,
0972         .is_crc             = false,
0973         .dest_buf_sz        = args->buf_sz,
0974     };
0975     struct crc32_write_args c_args        = {
0976         .dest_buf           = args->buf,
0977         .pid                = VIDTV_PAT_PID,
0978         .dest_buf_sz        = args->buf_sz,
0979     };
0980     u32 crc = INITIAL_CRC;
0981     u32 nbytes = 0;
0982 
0983     vidtv_psi_pat_table_update_sec_len(args->pat);
0984 
0985     h_args.crc = &crc;
0986 
0987     nbytes += vidtv_psi_table_header_write_into(&h_args);
0988 
0989     /* note that the field 'u16 programs' is not really part of the PAT */
0990 
0991     psi_args.crc = &crc;
0992 
0993     while (p) {
0994         /* copy the PAT programs */
0995         psi_args.from = p;
0996         /* skip the pointer */
0997         psi_args.len = sizeof(*p) -
0998                    sizeof(struct vidtv_psi_table_pat_program *);
0999         psi_args.dest_offset = args->offset + nbytes;
1000         psi_args.continuity_counter = args->continuity_counter;
1001 
1002         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1003 
1004         p = p->next;
1005     }
1006 
1007     c_args.dest_offset        = args->offset + nbytes;
1008     c_args.continuity_counter = args->continuity_counter;
1009     c_args.crc                = cpu_to_be32(crc);
1010 
1011     /* Write the CRC32 at the end */
1012     nbytes += table_section_crc32_write_into(&c_args);
1013 
1014     return nbytes;
1015 }
1016 
1017 void
1018 vidtv_psi_pat_table_destroy(struct vidtv_psi_table_pat *p)
1019 {
1020     vidtv_psi_pat_program_destroy(p->program);
1021     kfree(p);
1022 }
1023 
1024 struct vidtv_psi_table_pmt_stream*
1025 vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head,
1026               enum vidtv_psi_stream_types stream_type,
1027               u16 es_pid)
1028 {
1029     struct vidtv_psi_table_pmt_stream *stream;
1030     const u16 RESERVED1 = 0x07;
1031     const u16 RESERVED2 = 0x0f;
1032     const u16 ZERO = 0x0;
1033     u16 desc_loop_len;
1034 
1035     stream = kzalloc(sizeof(*stream), GFP_KERNEL);
1036     if (!stream)
1037         return NULL;
1038 
1039     stream->type = stream_type;
1040 
1041     stream->bitfield = cpu_to_be16((RESERVED1 << 13) | es_pid);
1042 
1043     desc_loop_len = vidtv_psi_desc_comp_loop_len(stream->descriptor);
1044 
1045     stream->bitfield2 = cpu_to_be16((RESERVED2 << 12) |
1046                     (ZERO << 10)      |
1047                     desc_loop_len);
1048     stream->next = NULL;
1049 
1050     if (head) {
1051         while (head->next)
1052             head = head->next;
1053 
1054         head->next = stream;
1055     }
1056 
1057     return stream;
1058 }
1059 
1060 void vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s)
1061 {
1062     struct vidtv_psi_table_pmt_stream *tmp_stream  = NULL;
1063     struct vidtv_psi_table_pmt_stream *curr_stream = s;
1064 
1065     while (curr_stream) {
1066         tmp_stream  = curr_stream;
1067         curr_stream = curr_stream->next;
1068         vidtv_psi_desc_destroy(tmp_stream->descriptor);
1069         kfree(tmp_stream);
1070     }
1071 }
1072 
1073 void vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt,
1074                  struct vidtv_psi_table_pmt_stream *s)
1075 {
1076     do {
1077         /* This function transfers ownership of s to the table */
1078         if (s == pmt->stream)
1079             return;
1080 
1081         pmt->stream = s;
1082         vidtv_psi_pmt_table_update_sec_len(pmt);
1083 
1084         s = NULL;
1085     } while (vidtv_psi_get_sec_len(&pmt->header) > MAX_SECTION_LEN);
1086 
1087     vidtv_psi_update_version_num(&pmt->header);
1088 }
1089 
1090 u16 vidtv_psi_pmt_get_pid(struct vidtv_psi_table_pmt *section,
1091               struct vidtv_psi_table_pat *pat)
1092 {
1093     struct vidtv_psi_table_pat_program *program = pat->program;
1094 
1095     /*
1096      * service_id is the same as program_number in the
1097      * corresponding program_map_section
1098      * see ETSI EN 300 468 v1.15.1 p. 24
1099      */
1100     while (program) {
1101         if (program->service_id == section->header.id)
1102             return vidtv_psi_get_pat_program_pid(program);
1103 
1104         program = program->next;
1105     }
1106 
1107     return TS_LAST_VALID_PID + 1; /* not found */
1108 }
1109 
1110 struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number,
1111                              u16 pcr_pid)
1112 {
1113     struct vidtv_psi_table_pmt *pmt;
1114     const u16 RESERVED1 = 0x07;
1115     const u16 RESERVED2 = 0x0f;
1116     const u16 SYNTAX = 0x1;
1117     const u16 ONES = 0x03;
1118     const u16 ZERO = 0x0;
1119     u16 desc_loop_len;
1120 
1121     pmt = kzalloc(sizeof(*pmt), GFP_KERNEL);
1122     if (!pmt)
1123         return NULL;
1124 
1125     if (!pcr_pid)
1126         pcr_pid = 0x1fff;
1127 
1128     pmt->header.table_id = 0x2;
1129 
1130     pmt->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ZERO << 14) | (ONES << 12));
1131 
1132     pmt->header.id = cpu_to_be16(program_number);
1133     pmt->header.current_next = 0x1;
1134 
1135     pmt->header.version = 0x1f;
1136 
1137     pmt->header.one2 = ONES;
1138     pmt->header.section_id   = 0;
1139     pmt->header.last_section = 0;
1140 
1141     pmt->bitfield = cpu_to_be16((RESERVED1 << 13) | pcr_pid);
1142 
1143     desc_loop_len = vidtv_psi_desc_comp_loop_len(pmt->descriptor);
1144 
1145     pmt->bitfield2 = cpu_to_be16((RESERVED2 << 12) |
1146                      (ZERO << 10)      |
1147                      desc_loop_len);
1148 
1149     vidtv_psi_pmt_table_update_sec_len(pmt);
1150 
1151     return pmt;
1152 }
1153 
1154 u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args)
1155 {
1156     struct vidtv_psi_desc *table_descriptor   = args->pmt->descriptor;
1157     struct vidtv_psi_table_pmt_stream *stream = args->pmt->stream;
1158     struct vidtv_psi_desc *stream_descriptor;
1159     u32 crc = INITIAL_CRC;
1160     u32 nbytes = 0;
1161     struct header_write_args h_args = {
1162         .dest_buf           = args->buf,
1163         .dest_offset        = args->offset,
1164         .h                  = &args->pmt->header,
1165         .pid                = args->pid,
1166         .continuity_counter = args->continuity_counter,
1167         .dest_buf_sz        = args->buf_sz,
1168     };
1169     struct psi_write_args psi_args  = {
1170         .dest_buf = args->buf,
1171         .from     = &args->pmt->bitfield,
1172         .len      = sizeof_field(struct vidtv_psi_table_pmt, bitfield) +
1173                 sizeof_field(struct vidtv_psi_table_pmt, bitfield2),
1174         .pid                = args->pid,
1175         .new_psi_section    = false,
1176         .is_crc             = false,
1177         .dest_buf_sz        = args->buf_sz,
1178         .crc                = &crc,
1179     };
1180     struct desc_write_args d_args   = {
1181         .dest_buf           = args->buf,
1182         .desc               = table_descriptor,
1183         .pid                = args->pid,
1184         .dest_buf_sz        = args->buf_sz,
1185     };
1186     struct crc32_write_args c_args  = {
1187         .dest_buf           = args->buf,
1188         .pid                = args->pid,
1189         .dest_buf_sz        = args->buf_sz,
1190     };
1191 
1192     vidtv_psi_pmt_table_update_sec_len(args->pmt);
1193 
1194     h_args.crc                = &crc;
1195 
1196     nbytes += vidtv_psi_table_header_write_into(&h_args);
1197 
1198     /* write the two bitfields */
1199     psi_args.dest_offset        = args->offset + nbytes;
1200     psi_args.continuity_counter = args->continuity_counter;
1201     nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1202 
1203     while (table_descriptor) {
1204         /* write the descriptors, if any */
1205         d_args.dest_offset        = args->offset + nbytes;
1206         d_args.continuity_counter = args->continuity_counter;
1207         d_args.crc                = &crc;
1208 
1209         nbytes += vidtv_psi_desc_write_into(&d_args);
1210 
1211         table_descriptor = table_descriptor->next;
1212     }
1213 
1214     psi_args.len += sizeof_field(struct vidtv_psi_table_pmt_stream, type);
1215     while (stream) {
1216         /* write the streams, if any */
1217         psi_args.from = stream;
1218         psi_args.dest_offset = args->offset + nbytes;
1219         psi_args.continuity_counter = args->continuity_counter;
1220 
1221         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1222 
1223         stream_descriptor = stream->descriptor;
1224 
1225         while (stream_descriptor) {
1226             /* write the stream descriptors, if any */
1227             d_args.dest_offset        = args->offset + nbytes;
1228             d_args.desc               = stream_descriptor;
1229             d_args.continuity_counter = args->continuity_counter;
1230             d_args.crc                = &crc;
1231 
1232             nbytes += vidtv_psi_desc_write_into(&d_args);
1233 
1234             stream_descriptor = stream_descriptor->next;
1235         }
1236 
1237         stream = stream->next;
1238     }
1239 
1240     c_args.dest_offset        = args->offset + nbytes;
1241     c_args.crc                = cpu_to_be32(crc);
1242     c_args.continuity_counter = args->continuity_counter;
1243 
1244     /* Write the CRC32 at the end */
1245     nbytes += table_section_crc32_write_into(&c_args);
1246 
1247     return nbytes;
1248 }
1249 
1250 void vidtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt)
1251 {
1252     vidtv_psi_desc_destroy(pmt->descriptor);
1253     vidtv_psi_pmt_stream_destroy(pmt->stream);
1254     kfree(pmt);
1255 }
1256 
1257 struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id,
1258                              u16 transport_stream_id)
1259 {
1260     struct vidtv_psi_table_sdt *sdt;
1261     const u16 RESERVED = 0xff;
1262     const u16 SYNTAX = 0x1;
1263     const u16 ONES = 0x03;
1264     const u16 ONE = 0x1;
1265 
1266     sdt  = kzalloc(sizeof(*sdt), GFP_KERNEL);
1267     if (!sdt)
1268         return NULL;
1269 
1270     sdt->header.table_id = 0x42;
1271     sdt->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12));
1272 
1273     /*
1274      * This is a 16-bit field which serves as a label for identification
1275      * of the TS, about which the SDT informs, from any other multiplex
1276      * within the delivery system.
1277      */
1278     sdt->header.id = cpu_to_be16(transport_stream_id);
1279     sdt->header.current_next = ONE;
1280 
1281     sdt->header.version = 0x1f;
1282 
1283     sdt->header.one2  = ONES;
1284     sdt->header.section_id   = 0;
1285     sdt->header.last_section = 0;
1286 
1287     /*
1288      * FIXME: The network_id range from 0xFF01 to 0xFFFF is used to
1289      * indicate temporary private use. For now, let's use the first
1290      * value.
1291      * This can be changed to something more useful, when support for
1292      * NIT gets added
1293      */
1294     sdt->network_id = cpu_to_be16(network_id);
1295     sdt->reserved = RESERVED;
1296 
1297     vidtv_psi_sdt_table_update_sec_len(sdt);
1298 
1299     return sdt;
1300 }
1301 
1302 u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args)
1303 {
1304     struct header_write_args h_args = {
1305         .dest_buf           = args->buf,
1306         .dest_offset        = args->offset,
1307         .h                  = &args->sdt->header,
1308         .pid                = VIDTV_SDT_PID,
1309         .dest_buf_sz        = args->buf_sz,
1310     };
1311     struct psi_write_args psi_args  = {
1312         .dest_buf = args->buf,
1313         .len = sizeof_field(struct vidtv_psi_table_sdt, network_id) +
1314                sizeof_field(struct vidtv_psi_table_sdt, reserved),
1315         .pid                = VIDTV_SDT_PID,
1316         .new_psi_section    = false,
1317         .is_crc             = false,
1318         .dest_buf_sz        = args->buf_sz,
1319     };
1320     struct desc_write_args d_args   = {
1321         .dest_buf           = args->buf,
1322         .pid                = VIDTV_SDT_PID,
1323         .dest_buf_sz        = args->buf_sz,
1324     };
1325     struct crc32_write_args c_args  = {
1326         .dest_buf           = args->buf,
1327         .pid                = VIDTV_SDT_PID,
1328         .dest_buf_sz        = args->buf_sz,
1329     };
1330     struct vidtv_psi_table_sdt_service *service = args->sdt->service;
1331     struct vidtv_psi_desc *service_desc;
1332     u32 nbytes  = 0;
1333     u32 crc = INITIAL_CRC;
1334 
1335     /* see ETSI EN 300 468 v1.15.1 p. 11 */
1336 
1337     vidtv_psi_sdt_table_update_sec_len(args->sdt);
1338 
1339     h_args.continuity_counter = args->continuity_counter;
1340     h_args.crc                = &crc;
1341 
1342     nbytes += vidtv_psi_table_header_write_into(&h_args);
1343 
1344     psi_args.from               = &args->sdt->network_id;
1345     psi_args.dest_offset        = args->offset + nbytes;
1346     psi_args.continuity_counter = args->continuity_counter;
1347     psi_args.crc                = &crc;
1348 
1349     /* copy u16 network_id + u8 reserved)*/
1350     nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1351 
1352     /* skip both pointers at the end */
1353     psi_args.len = sizeof(struct vidtv_psi_table_sdt_service) -
1354                sizeof(struct vidtv_psi_desc *) -
1355                sizeof(struct vidtv_psi_table_sdt_service *);
1356 
1357     while (service) {
1358         /* copy the services, if any */
1359         psi_args.from = service;
1360         psi_args.dest_offset = args->offset + nbytes;
1361         psi_args.continuity_counter = args->continuity_counter;
1362 
1363         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1364 
1365         service_desc = service->descriptor;
1366 
1367         while (service_desc) {
1368             /* copy the service descriptors, if any */
1369             d_args.dest_offset        = args->offset + nbytes;
1370             d_args.desc               = service_desc;
1371             d_args.continuity_counter = args->continuity_counter;
1372             d_args.crc                = &crc;
1373 
1374             nbytes += vidtv_psi_desc_write_into(&d_args);
1375 
1376             service_desc = service_desc->next;
1377         }
1378 
1379         service = service->next;
1380     }
1381 
1382     c_args.dest_offset        = args->offset + nbytes;
1383     c_args.crc                = cpu_to_be32(crc);
1384     c_args.continuity_counter = args->continuity_counter;
1385 
1386     /* Write the CRC at the end */
1387     nbytes += table_section_crc32_write_into(&c_args);
1388 
1389     return nbytes;
1390 }
1391 
1392 void vidtv_psi_sdt_table_destroy(struct vidtv_psi_table_sdt *sdt)
1393 {
1394     vidtv_psi_sdt_service_destroy(sdt->service);
1395     kfree(sdt);
1396 }
1397 
1398 struct vidtv_psi_table_sdt_service
1399 *vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head,
1400                 u16 service_id,
1401                 bool eit_schedule,
1402                 bool eit_present_following)
1403 {
1404     struct vidtv_psi_table_sdt_service *service;
1405 
1406     service = kzalloc(sizeof(*service), GFP_KERNEL);
1407     if (!service)
1408         return NULL;
1409 
1410     /*
1411      * ETSI 300 468: this is a 16bit field which serves as a label to
1412      * identify this service from any other service within the TS.
1413      * The service id is the same as the program number in the
1414      * corresponding program_map_section
1415      */
1416     service->service_id            = cpu_to_be16(service_id);
1417     service->EIT_schedule          = eit_schedule;
1418     service->EIT_present_following = eit_present_following;
1419     service->reserved              = 0x3f;
1420 
1421     service->bitfield = cpu_to_be16(RUNNING << 13);
1422 
1423     if (head) {
1424         while (head->next)
1425             head = head->next;
1426 
1427         head->next = service;
1428     }
1429 
1430     return service;
1431 }
1432 
1433 void
1434 vidtv_psi_sdt_service_destroy(struct vidtv_psi_table_sdt_service *service)
1435 {
1436     struct vidtv_psi_table_sdt_service *curr = service;
1437     struct vidtv_psi_table_sdt_service *tmp  = NULL;
1438 
1439     while (curr) {
1440         tmp  = curr;
1441         curr = curr->next;
1442         vidtv_psi_desc_destroy(tmp->descriptor);
1443         kfree(tmp);
1444     }
1445 }
1446 
1447 void
1448 vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt,
1449                  struct vidtv_psi_table_sdt_service *service)
1450 {
1451     do {
1452         if (service == sdt->service)
1453             return;
1454 
1455         sdt->service = service;
1456 
1457         /* recompute section length */
1458         vidtv_psi_sdt_table_update_sec_len(sdt);
1459 
1460         service = NULL;
1461     } while (vidtv_psi_get_sec_len(&sdt->header) > MAX_SECTION_LEN);
1462 
1463     vidtv_psi_update_version_num(&sdt->header);
1464 }
1465 
1466 /*
1467  * PMTs contain information about programs. For each program,
1468  * there is one PMT section. This function will create a section
1469  * for each program found in the PAT
1470  */
1471 struct vidtv_psi_table_pmt**
1472 vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat,
1473                         u16 pcr_pid)
1474 
1475 {
1476     struct vidtv_psi_table_pat_program *program;
1477     struct vidtv_psi_table_pmt **pmt_secs;
1478     u32 i = 0, num_pmt = 0;
1479 
1480     /*
1481      * The number of PMT entries is the number of PAT entries
1482      * that contain service_id. That exclude special tables, like NIT
1483      */
1484     program = pat->program;
1485     while (program) {
1486         if (program->service_id)
1487             num_pmt++;
1488         program = program->next;
1489     }
1490 
1491     pmt_secs = kcalloc(num_pmt,
1492                sizeof(struct vidtv_psi_table_pmt *),
1493                GFP_KERNEL);
1494     if (!pmt_secs)
1495         return NULL;
1496 
1497     for (program = pat->program; program; program = program->next) {
1498         if (!program->service_id)
1499             continue;
1500         pmt_secs[i] = vidtv_psi_pmt_table_init(be16_to_cpu(program->service_id),
1501                                pcr_pid);
1502 
1503         if (!pmt_secs[i]) {
1504             while (i > 0) {
1505                 i--;
1506                 vidtv_psi_pmt_table_destroy(pmt_secs[i]);
1507             }
1508             return NULL;
1509         }
1510         i++;
1511     }
1512     pat->num_pmt = num_pmt;
1513 
1514     return pmt_secs;
1515 }
1516 
1517 /* find the PMT section associated with 'program_num' */
1518 struct vidtv_psi_table_pmt
1519 *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections,
1520             u16 nsections,
1521             u16 program_num)
1522 {
1523     struct vidtv_psi_table_pmt *sec = NULL;
1524     u32 i;
1525 
1526     for (i = 0; i < nsections; ++i) {
1527         sec = pmt_sections[i];
1528         if (be16_to_cpu(sec->header.id) == program_num)
1529             return sec;
1530     }
1531 
1532     return NULL; /* not found */
1533 }
1534 
1535 static void vidtv_psi_nit_table_update_sec_len(struct vidtv_psi_table_nit *nit)
1536 {
1537     u16 length = 0;
1538     struct vidtv_psi_table_transport *t = nit->transport;
1539     u16 desc_loop_len;
1540     u16 transport_loop_len = 0;
1541 
1542     /*
1543      * from immediately after 'section_length' until
1544      * 'network_descriptor_length'
1545      */
1546     length += NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN;
1547 
1548     desc_loop_len = vidtv_psi_desc_comp_loop_len(nit->descriptor);
1549     vidtv_psi_set_desc_loop_len(&nit->bitfield, desc_loop_len, 12);
1550 
1551     length += desc_loop_len;
1552 
1553     length += sizeof_field(struct vidtv_psi_table_nit, bitfield2);
1554 
1555     while (t) {
1556         /* skip both pointers at the end */
1557         transport_loop_len += sizeof(struct vidtv_psi_table_transport) -
1558                       sizeof(struct vidtv_psi_desc *) -
1559                       sizeof(struct vidtv_psi_table_transport *);
1560 
1561         length += transport_loop_len;
1562 
1563         desc_loop_len = vidtv_psi_desc_comp_loop_len(t->descriptor);
1564         vidtv_psi_set_desc_loop_len(&t->bitfield, desc_loop_len, 12);
1565 
1566         length += desc_loop_len;
1567 
1568         t = t->next;
1569     }
1570 
1571     // Actually sets the transport stream loop len, maybe rename this function later
1572     vidtv_psi_set_desc_loop_len(&nit->bitfield2, transport_loop_len, 12);
1573     length += CRC_SIZE_IN_BYTES;
1574 
1575     vidtv_psi_set_sec_len(&nit->header, length);
1576 }
1577 
1578 struct vidtv_psi_table_nit
1579 *vidtv_psi_nit_table_init(u16 network_id,
1580               u16 transport_stream_id,
1581               char *network_name,
1582               struct vidtv_psi_desc_service_list_entry *service_list)
1583 {
1584     struct vidtv_psi_table_transport *transport;
1585     struct vidtv_psi_table_nit *nit;
1586     const u16 SYNTAX = 0x1;
1587     const u16 ONES = 0x03;
1588     const u16 ONE = 0x1;
1589 
1590     nit = kzalloc(sizeof(*nit), GFP_KERNEL);
1591     if (!nit)
1592         return NULL;
1593 
1594     transport = kzalloc(sizeof(*transport), GFP_KERNEL);
1595     if (!transport)
1596         goto free_nit;
1597 
1598     nit->header.table_id = 0x40; // ACTUAL_NETWORK
1599 
1600     nit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12));
1601 
1602     nit->header.id = cpu_to_be16(network_id);
1603     nit->header.current_next = ONE;
1604 
1605     nit->header.version = 0x1f;
1606 
1607     nit->header.one2  = ONES;
1608     nit->header.section_id   = 0;
1609     nit->header.last_section = 0;
1610 
1611     nit->bitfield = cpu_to_be16(0xf);
1612     nit->bitfield2 = cpu_to_be16(0xf);
1613 
1614     nit->descriptor = (struct vidtv_psi_desc *)
1615               vidtv_psi_network_name_desc_init(NULL, network_name);
1616     if (!nit->descriptor)
1617         goto free_transport;
1618 
1619     transport->transport_id = cpu_to_be16(transport_stream_id);
1620     transport->network_id = cpu_to_be16(network_id);
1621     transport->bitfield = cpu_to_be16(0xf);
1622     transport->descriptor = (struct vidtv_psi_desc *)
1623                 vidtv_psi_service_list_desc_init(NULL, service_list);
1624     if (!transport->descriptor)
1625         goto free_nit_desc;
1626 
1627     nit->transport = transport;
1628 
1629     vidtv_psi_nit_table_update_sec_len(nit);
1630 
1631     return nit;
1632 
1633 free_nit_desc:
1634     vidtv_psi_desc_destroy((struct vidtv_psi_desc *)nit->descriptor);
1635 
1636 free_transport:
1637     kfree(transport);
1638 free_nit:
1639     kfree(nit);
1640     return NULL;
1641 }
1642 
1643 u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args)
1644 {
1645     struct header_write_args h_args = {
1646         .dest_buf           = args->buf,
1647         .dest_offset        = args->offset,
1648         .h                  = &args->nit->header,
1649         .pid                = VIDTV_NIT_PID,
1650         .dest_buf_sz        = args->buf_sz,
1651     };
1652     struct psi_write_args psi_args  = {
1653         .dest_buf           = args->buf,
1654         .from               = &args->nit->bitfield,
1655         .len                = sizeof_field(struct vidtv_psi_table_nit, bitfield),
1656         .pid                = VIDTV_NIT_PID,
1657         .new_psi_section    = false,
1658         .is_crc             = false,
1659         .dest_buf_sz        = args->buf_sz,
1660     };
1661     struct desc_write_args d_args   = {
1662         .dest_buf           = args->buf,
1663         .pid                = VIDTV_NIT_PID,
1664         .dest_buf_sz        = args->buf_sz,
1665     };
1666     struct crc32_write_args c_args  = {
1667         .dest_buf           = args->buf,
1668         .pid                = VIDTV_NIT_PID,
1669         .dest_buf_sz        = args->buf_sz,
1670     };
1671     struct vidtv_psi_desc *table_descriptor     = args->nit->descriptor;
1672     struct vidtv_psi_table_transport *transport = args->nit->transport;
1673     struct vidtv_psi_desc *transport_descriptor;
1674     u32 crc = INITIAL_CRC;
1675     u32 nbytes = 0;
1676 
1677     vidtv_psi_nit_table_update_sec_len(args->nit);
1678 
1679     h_args.continuity_counter = args->continuity_counter;
1680     h_args.crc                = &crc;
1681 
1682     nbytes += vidtv_psi_table_header_write_into(&h_args);
1683 
1684     /* write the bitfield */
1685 
1686     psi_args.dest_offset        = args->offset + nbytes;
1687     psi_args.continuity_counter = args->continuity_counter;
1688     psi_args.crc                = &crc;
1689 
1690     nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1691 
1692     while (table_descriptor) {
1693         /* write the descriptors, if any */
1694         d_args.dest_offset        = args->offset + nbytes;
1695         d_args.desc               = table_descriptor;
1696         d_args.continuity_counter = args->continuity_counter;
1697         d_args.crc                = &crc;
1698 
1699         nbytes += vidtv_psi_desc_write_into(&d_args);
1700 
1701         table_descriptor = table_descriptor->next;
1702     }
1703 
1704     /* write the second bitfield */
1705     psi_args.from = &args->nit->bitfield2;
1706     psi_args.len = sizeof_field(struct vidtv_psi_table_nit, bitfield2);
1707     psi_args.dest_offset = args->offset + nbytes;
1708 
1709     nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1710 
1711     psi_args.len  = sizeof_field(struct vidtv_psi_table_transport, transport_id) +
1712             sizeof_field(struct vidtv_psi_table_transport, network_id)   +
1713             sizeof_field(struct vidtv_psi_table_transport, bitfield);
1714     while (transport) {
1715         /* write the transport sections, if any */
1716         psi_args.from = transport;
1717         psi_args.dest_offset = args->offset + nbytes;
1718 
1719         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1720 
1721         transport_descriptor = transport->descriptor;
1722 
1723         while (transport_descriptor) {
1724             /* write the transport descriptors, if any */
1725             d_args.dest_offset        = args->offset + nbytes;
1726             d_args.desc               = transport_descriptor;
1727             d_args.continuity_counter = args->continuity_counter;
1728             d_args.crc                = &crc;
1729 
1730             nbytes += vidtv_psi_desc_write_into(&d_args);
1731 
1732             transport_descriptor = transport_descriptor->next;
1733         }
1734 
1735         transport = transport->next;
1736     }
1737 
1738     c_args.dest_offset        = args->offset + nbytes;
1739     c_args.crc                = cpu_to_be32(crc);
1740     c_args.continuity_counter = args->continuity_counter;
1741 
1742     /* Write the CRC32 at the end */
1743     nbytes += table_section_crc32_write_into(&c_args);
1744 
1745     return nbytes;
1746 }
1747 
1748 static void vidtv_psi_transport_destroy(struct vidtv_psi_table_transport *t)
1749 {
1750     struct vidtv_psi_table_transport *tmp_t  = NULL;
1751     struct vidtv_psi_table_transport *curr_t = t;
1752 
1753     while (curr_t) {
1754         tmp_t  = curr_t;
1755         curr_t = curr_t->next;
1756         vidtv_psi_desc_destroy(tmp_t->descriptor);
1757         kfree(tmp_t);
1758     }
1759 }
1760 
1761 void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit)
1762 {
1763     vidtv_psi_desc_destroy(nit->descriptor);
1764     vidtv_psi_transport_destroy(nit->transport);
1765     kfree(nit);
1766 }
1767 
1768 void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit)
1769 {
1770     struct vidtv_psi_table_eit_event *e = eit->event;
1771     u16 desc_loop_len;
1772     u16 length = 0;
1773 
1774     /*
1775      * from immediately after 'section_length' until
1776      * 'last_table_id'
1777      */
1778     length += EIT_LEN_UNTIL_LAST_TABLE_ID;
1779 
1780     while (e) {
1781         /* skip both pointers at the end */
1782         length += sizeof(struct vidtv_psi_table_eit_event) -
1783               sizeof(struct vidtv_psi_desc *) -
1784               sizeof(struct vidtv_psi_table_eit_event *);
1785 
1786         desc_loop_len = vidtv_psi_desc_comp_loop_len(e->descriptor);
1787         vidtv_psi_set_desc_loop_len(&e->bitfield, desc_loop_len, 12);
1788 
1789         length += desc_loop_len;
1790 
1791         e = e->next;
1792     }
1793 
1794     length += CRC_SIZE_IN_BYTES;
1795 
1796     vidtv_psi_set_sec_len(&eit->header, length);
1797 }
1798 
1799 void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit,
1800                 struct vidtv_psi_table_eit_event *e)
1801 {
1802     do {
1803         if (e == eit->event)
1804             return;
1805 
1806         eit->event = e;
1807         vidtv_psi_eit_table_update_sec_len(eit);
1808 
1809         e = NULL;
1810     } while (vidtv_psi_get_sec_len(&eit->header) > EIT_MAX_SECTION_LEN);
1811 
1812     vidtv_psi_update_version_num(&eit->header);
1813 }
1814 
1815 struct vidtv_psi_table_eit
1816 *vidtv_psi_eit_table_init(u16 network_id,
1817               u16 transport_stream_id,
1818               __be16 service_id)
1819 {
1820     struct vidtv_psi_table_eit *eit;
1821     const u16 SYNTAX = 0x1;
1822     const u16 ONE = 0x1;
1823     const u16 ONES = 0x03;
1824 
1825     eit = kzalloc(sizeof(*eit), GFP_KERNEL);
1826     if (!eit)
1827         return NULL;
1828 
1829     eit->header.table_id = 0x4e; //actual_transport_stream: present/following
1830 
1831     eit->header.bitfield = cpu_to_be16((SYNTAX << 15) | (ONE << 14) | (ONES << 12));
1832 
1833     eit->header.id = service_id;
1834     eit->header.current_next = ONE;
1835 
1836     eit->header.version = 0x1f;
1837 
1838     eit->header.one2  = ONES;
1839     eit->header.section_id   = 0;
1840     eit->header.last_section = 0;
1841 
1842     eit->transport_id = cpu_to_be16(transport_stream_id);
1843     eit->network_id = cpu_to_be16(network_id);
1844 
1845     eit->last_segment = eit->header.last_section; /* not implemented */
1846     eit->last_table_id = eit->header.table_id; /* not implemented */
1847 
1848     vidtv_psi_eit_table_update_sec_len(eit);
1849 
1850     return eit;
1851 }
1852 
1853 u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args)
1854 {
1855     struct header_write_args h_args = {
1856         .dest_buf        = args->buf,
1857         .dest_offset     = args->offset,
1858         .h               = &args->eit->header,
1859         .pid             = VIDTV_EIT_PID,
1860         .dest_buf_sz     = args->buf_sz,
1861     };
1862     struct psi_write_args psi_args  = {
1863         .dest_buf        = args->buf,
1864         .len             = sizeof_field(struct vidtv_psi_table_eit, transport_id) +
1865                    sizeof_field(struct vidtv_psi_table_eit, network_id)   +
1866                    sizeof_field(struct vidtv_psi_table_eit, last_segment) +
1867                    sizeof_field(struct vidtv_psi_table_eit, last_table_id),
1868         .pid             = VIDTV_EIT_PID,
1869         .new_psi_section = false,
1870         .is_crc          = false,
1871         .dest_buf_sz     = args->buf_sz,
1872     };
1873     struct desc_write_args d_args   = {
1874         .dest_buf           = args->buf,
1875         .pid                = VIDTV_EIT_PID,
1876         .dest_buf_sz        = args->buf_sz,
1877     };
1878     struct crc32_write_args c_args  = {
1879         .dest_buf           = args->buf,
1880         .pid                = VIDTV_EIT_PID,
1881         .dest_buf_sz        = args->buf_sz,
1882     };
1883     struct vidtv_psi_table_eit_event *event = args->eit->event;
1884     struct vidtv_psi_desc *event_descriptor;
1885     u32 crc = INITIAL_CRC;
1886     u32 nbytes  = 0;
1887 
1888     vidtv_psi_eit_table_update_sec_len(args->eit);
1889 
1890     h_args.continuity_counter = args->continuity_counter;
1891     h_args.crc                = &crc;
1892 
1893     nbytes += vidtv_psi_table_header_write_into(&h_args);
1894 
1895     psi_args.from               = &args->eit->transport_id;
1896     psi_args.dest_offset        = args->offset + nbytes;
1897     psi_args.continuity_counter = args->continuity_counter;
1898     psi_args.crc                = &crc;
1899 
1900     nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1901 
1902     /* skip both pointers at the end */
1903     psi_args.len = sizeof(struct vidtv_psi_table_eit_event) -
1904                sizeof(struct vidtv_psi_desc *) -
1905                sizeof(struct vidtv_psi_table_eit_event *);
1906     while (event) {
1907         /* copy the events, if any */
1908         psi_args.from = event;
1909         psi_args.dest_offset = args->offset + nbytes;
1910 
1911         nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1912 
1913         event_descriptor = event->descriptor;
1914 
1915         while (event_descriptor) {
1916             /* copy the event descriptors, if any */
1917             d_args.dest_offset        = args->offset + nbytes;
1918             d_args.desc               = event_descriptor;
1919             d_args.continuity_counter = args->continuity_counter;
1920             d_args.crc                = &crc;
1921 
1922             nbytes += vidtv_psi_desc_write_into(&d_args);
1923 
1924             event_descriptor = event_descriptor->next;
1925         }
1926 
1927         event = event->next;
1928     }
1929 
1930     c_args.dest_offset        = args->offset + nbytes;
1931     c_args.crc                = cpu_to_be32(crc);
1932     c_args.continuity_counter = args->continuity_counter;
1933 
1934     /* Write the CRC at the end */
1935     nbytes += table_section_crc32_write_into(&c_args);
1936 
1937     return nbytes;
1938 }
1939 
1940 struct vidtv_psi_table_eit_event
1941 *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id)
1942 {
1943     const u8 DURATION[] = {0x23, 0x59, 0x59}; /* BCD encoded */
1944     struct vidtv_psi_table_eit_event *e;
1945     struct timespec64 ts;
1946     struct tm time;
1947     int mjd, l;
1948     __be16 mjd_be;
1949 
1950     e = kzalloc(sizeof(*e), GFP_KERNEL);
1951     if (!e)
1952         return NULL;
1953 
1954     e->event_id = cpu_to_be16(event_id);
1955 
1956     ts = ktime_to_timespec64(ktime_get_real());
1957     time64_to_tm(ts.tv_sec, 0, &time);
1958 
1959     /* Convert date to Modified Julian Date - per EN 300 468 Annex C */
1960     if (time.tm_mon < 2)
1961         l = 1;
1962     else
1963         l = 0;
1964 
1965     mjd = 14956 + time.tm_mday;
1966     mjd += (time.tm_year - l) * 36525 / 100;
1967     mjd += (time.tm_mon + 2 + l * 12) * 306001 / 10000;
1968     mjd_be = cpu_to_be16(mjd);
1969 
1970     /*
1971      * Store MJD and hour/min/sec to the event.
1972      *
1973      * Let's make the event to start on a full hour
1974      */
1975     memcpy(e->start_time, &mjd_be, sizeof(mjd_be));
1976     e->start_time[2] = bin2bcd(time.tm_hour);
1977     e->start_time[3] = 0;
1978     e->start_time[4] = 0;
1979 
1980     /*
1981      * TODO: for now, the event will last for a day. Should be
1982      * enough for testing purposes, but if one runs the driver
1983      * for more than that, the current event will become invalid.
1984      * So, we need a better code here in order to change the start
1985      * time once the event expires.
1986      */
1987     memcpy(e->duration, DURATION, sizeof(e->duration));
1988 
1989     e->bitfield = cpu_to_be16(RUNNING << 13);
1990 
1991     if (head) {
1992         while (head->next)
1993             head = head->next;
1994 
1995         head->next = e;
1996     }
1997 
1998     return e;
1999 }
2000 
2001 void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e)
2002 {
2003     struct vidtv_psi_table_eit_event *tmp_e  = NULL;
2004     struct vidtv_psi_table_eit_event *curr_e = e;
2005 
2006     while (curr_e) {
2007         tmp_e  = curr_e;
2008         curr_e = curr_e->next;
2009         vidtv_psi_desc_destroy(tmp_e->descriptor);
2010         kfree(tmp_e);
2011     }
2012 }
2013 
2014 void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit)
2015 {
2016     vidtv_psi_eit_event_destroy(eit->event);
2017     kfree(eit);
2018 }