0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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
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
0154
0155
0156
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,
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
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
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
0206
0207
0208 vidtv_ts_inc_cc(args->continuity_counter);
0209 }
0210
0211
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
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
0230 remaining_len -= payload_write_len;
0231 payload_offset += payload_write_len;
0232 }
0233
0234
0235
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
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
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;
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
0774
0775
0776 length += PAT_LEN_UNTIL_LAST_SECTION_NUMBER;
0777
0778
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
0795
0796
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
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
0830
0831
0832
0833
0834
0835 length += SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE;
0836
0837 while (s) {
0838
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
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
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
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
0990
0991 psi_args.crc = &crc;
0992
0993 while (p) {
0994
0995 psi_args.from = p;
0996
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
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
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
1097
1098
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;
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
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
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
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
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
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
1275
1276
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
1289
1290
1291
1292
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
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
1350 nbytes += vidtv_psi_ts_psi_write_into(&psi_args);
1351
1352
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
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
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
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
1412
1413
1414
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
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
1468
1469
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
1482
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
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;
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
1544
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
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
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;
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
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
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
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
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
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
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
1776
1777
1778 length += EIT_LEN_UNTIL_LAST_TABLE_ID;
1779
1780 while (e) {
1781
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;
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;
1846 eit->last_table_id = eit->header.table_id;
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
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
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
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
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};
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
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
1972
1973
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
1982
1983
1984
1985
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 }