Annotation of multiplexer/en300468ts.c, revision 1.4
1.1 oskar 1: /*
2: * SI table generator (EN 300468)
1.3 oskar 3: * Copyright (C) 2004,2005 Oskar Schirmer (schirmer@scara.com)
1.1 oskar 4: *
5: * This program is free software; you can redistribute it and/or modify
6: * it under the terms of the GNU General Public License as published by
7: * the Free Software Foundation; either version 2 of the License, or
8: * (at your option) any later version.
9: *
10: * This program is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: * GNU General Public License for more details.
14: *
15: * You should have received a copy of the GNU General Public License
16: * along with this program; if not, write to the Free Software
17: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18: */
19:
20: /*
21: * Module: SI table generator
22: * Purpose: From a list of desciptive files generate SI tables and feed
23: * them to stdout.
24: * known bug: missing check for section length <= 1021
25: */
26:
27: //#define DEBUG
28:
29: #include <limits.h>
30: #include <unistd.h>
31: #include <stdio.h>
32: #include <stdlib.h>
33: #include <sys/types.h>
34: #include <sys/stat.h>
35: #include <fcntl.h>
36: #include <signal.h>
37: #include <sys/poll.h>
38: #include <errno.h>
39: #include <string.h>
40: #include <ctype.h>
41: #include <sys/time.h>
42:
43: #include "crc32.h"
44:
45: #ifdef PATH_MAX
46: #define MY_PATH_MAX PATH_MAX
47: #else
48: #define MY_PATH_MAX 4096
49: #endif
50:
51: static struct pollfd *pfd = NULL;
52: static int npfd = 0;
53: static int ipfd;
54:
55: #define TABLE_PID_FIRST 0x10
56: #define TABLE_PID_LAST 0x1F
57: #define TABBUF_SIZE (1<<15)
58: #define MAX_PSI_SIZE (4096+1)
59:
60: static unsigned int tabin[TABLE_PID_LAST-TABLE_PID_FIRST+1];
61: static unsigned int tabinold[TABLE_PID_LAST-TABLE_PID_FIRST+1];
62: static unsigned int tabout[TABLE_PID_LAST-TABLE_PID_FIRST+1];
63: static unsigned char conticnt[TABLE_PID_LAST-TABLE_PID_FIRST+1];
64: static unsigned char *tabbuf[TABLE_PID_LAST-TABLE_PID_FIRST+1];
65:
66: #define TABLEID_FIRST 0x40
67: #define TABLEID_LAST 0x7F
68:
69: static unsigned char nextversion[TABLEID_LAST-TABLEID_FIRST+1];
70:
71: #define TS_PACKET_SIZE 188
72: #define TS_HEADSLEN 3
73: #define TS_PACKET_HEADSIZE 4
1.4 ! oskar 74: #define TS_PFIELDLEN 1
1.1 oskar 75: #define TS_SYNC_BYTE 0x47
76: #define OUTBUF_PACKETS 256
77: #define OUTBUF_SIZE (TS_PACKET_SIZE*OUTBUF_PACKETS)
78:
79: static unsigned int outin = 0;
80: static unsigned int outout = 0;
81: static unsigned char outbuf[OUTBUF_SIZE];
82:
83: static void pollfd_init()
84: {
85: ipfd = 0;
86: }
87:
88: static int pollfd_add(int f, short e)
89: {
90: if (npfd <= ipfd) {
91: npfd = 2*npfd+1;
92: pfd = realloc(pfd, npfd * sizeof(struct pollfd));
93: }
94: pfd[ipfd].fd = f;
95: pfd[ipfd].events = e;
96: return ipfd++;
97: }
98:
99: static int pollfd_poll(int timeout)
100: {
101: return poll(pfd, ipfd, timeout);
102: }
103:
104: static int pollfd_rev(int i)
105: {
106: return pfd[i].revents;
107: }
108:
109: static void signalhandler(int sig)
110: {
111: exit(0);
112: }
113:
114: static void system_init()
115: {
116: signal(SIGINT, (void *) (*signalhandler));
117: signal(SIGPIPE, SIG_IGN);
118: }
119:
120: static void unblockf(int f)
121: {
122: int r;
123: r = fcntl(f, F_GETFL);
124: if (r >= 0) {
125: r = fcntl(f, F_SETFL, r | O_NONBLOCK);
126: }
127: if (r < 0) {
128: fprintf(stderr, "fcntl failed(%d): %d\n", errno, f);
129: }
130: }
131:
132: enum enumsi {
133: nit,
134: sdt,
135: bat,
136: eit,
137: rst,
138: tdt,
139: tot,
140: sit,
141: dit,
142: num_si,
143: si_none = -1
144: };
145:
146: #define DESCR_FIRST 0x40
147: #define DESCR_LAST 0x6E
148: #define PMT_POSS 0
149:
150: static unsigned char descrcnt[DESCR_LAST-DESCR_FIRST+1];
151:
152: const static unsigned char possible_descr[DESCR_LAST-DESCR_FIRST+1] = {
153: (1<<nit),
154: (1<<nit) | (1<<bat),
155: 0 /* (1<<nit) | (1<<bat) | (1<<sdt) | (1<<eit) | (1<<sit) */,
156: (1<<nit),
157: (1<<nit),
158: PMT_POSS,
159: PMT_POSS,
160: (1<<bat) | (1<<sdt) | (1<<sit),
161: (1<<sdt) | (1<<sit),
162: (1<<bat) | (1<<sdt) | (1<<sit),
163: (1<<nit) | (1<<bat) | (1<<sdt) | (1<<eit) | (1<<sit),
164: (1<<sdt) | (1<<sit),
165: (1<<sdt) | (1<<sit),
166: (1<<eit) | (1<<sit),
167: (1<<eit) | (1<<sit),
168: (1<<eit) | (1<<sit),
169: (1<<eit) | (1<<sit),
170: (1<<sdt) | PMT_POSS | (1<<sit),
171: PMT_POSS,
172: (1<<bat) | (1<<sdt) | (1<<eit) | (1<<sit),
173: (1<<eit) | (1<<sit),
174: (1<<eit) | (1<<sit),
175: PMT_POSS,
176: (1<<sdt) | (1<<eit) | (1<<sit),
177: (1<<tot),
178: PMT_POSS,
179: (1<<nit),
180: (1<<nit),
181: (1<<bat),
182: (1<<sdt) | (1<<sit),
183: (1<<eit) | (1<<sit),
184: (1<<nit) | (1<<bat) | (1<<sdt) | (1<<eit) | PMT_POSS | (1<<sit),
185: PMT_POSS,
186: (1<<eit) | (1<<sit),
187: (1<<nit),
188: (1<<sit),
189: (1<<sdt) | (1<<eit) | (1<<sit),
190: PMT_POSS,
191: PMT_POSS,
192: 0,
193: 0,
194: (1<<eit),
195: PMT_POSS,
196: PMT_POSS,
197: (1<<nit),
198: (1<<nit),
199: (1<<nit)
200: };
201:
202: #define LOOP_DEPTH 4
203: #define REALLOC_CHUNK 32
204:
205: struct sitab {
206: struct sitab *next;
207: char typ;
208: unsigned char version;
209: unsigned char tableid;
210: long pid;
211: long freqmsec;
212: enum enumsi esi;
213: unsigned long *tab;
214: union {
215: struct {
216: int tablen;
217: int itab;
218: int fd;
219: int isdescr; /* 0: main table, >0: descr loop depth */
220: int descrtag;
221: int isyn;
222: int isyntab;
223: int numcount;
224: int loopbegin[LOOP_DEPTH];
225: int loopcount[LOOP_DEPTH];
226: int ibuf;
227: char buf[256];
228: } a;
229: struct {
230: struct timeval next;
231: } s;
232: } u;
233: unsigned char descrnum[DESCR_LAST-DESCR_FIRST+1];
234: };
235:
236: static struct sitab *newtab = NULL;
237: static struct sitab *runtab = NULL;
238:
239: #define SYNTAX_END 0
240: #define SYNTAX_LOOPEND 1
241: #define SYNTAX_LOOP 2
242: #define SYNTAX_DESCR 3
243: #define SYNTAX_DESCRTAG 4
244: #define SYNTAX_DATETIME 5
245: #define SYNTAX_STRING 6
246: #define SYNTAX_NUMBER(name) -1
247:
248: const static signed char syntax_network_name[] = {
249: SYNTAX_DESCRTAG,
250: SYNTAX_STRING,
251: SYNTAX_END
252: };
253:
254: static unsigned char *gen_network_name(struct sitab *st, unsigned char *p,
255: unsigned long **tt)
256: {
257: unsigned char *d = p;
258: unsigned long *t = *tt;
259: int i;
260: i = *t++;
261: memcpy(d, t, i);
262: d += i;
263: t += (i + sizeof(long) - 1) / sizeof(long);
264: *tt = t;
265: return d;
266: }
267:
268: const static signed char syntax_service_list[] = {
269: SYNTAX_DESCRTAG,
270: SYNTAX_LOOP,
271: SYNTAX_NUMBER(service_id)
272: SYNTAX_NUMBER(service_type),
273: SYNTAX_END
274: };
275:
276: static unsigned char *gen_service_list(struct sitab *st, unsigned char *p,
277: unsigned long **tt)
278: {
279: unsigned char *d = p;
280: unsigned long *t = *tt;
281: int i;
282: i = *t++;
283: while (i > 0) {
284: *d++ = *t >> 8;
285: *d++ = *t++;
286: *d++ = *t++;
287: i -= 1;
288: }
289: *tt = t;
290: return d;
291: }
292:
293: const static signed char syntax_satellite_delivery_system[] = {
294: SYNTAX_DESCRTAG,
295: SYNTAX_NUMBER(frequency)
296: SYNTAX_NUMBER(orbital_position)
297: SYNTAX_NUMBER(west_east_flag)
298: SYNTAX_NUMBER(polarization)
299: SYNTAX_NUMBER(modulation)
300: SYNTAX_NUMBER(symbol_rate)
301: SYNTAX_NUMBER(fec_inner),
302: SYNTAX_END
303: };
304:
305: static unsigned char *gen_satellite_delivery_system(struct sitab *st,
306: unsigned char *p, unsigned long **tt)
307: {
308: unsigned char *d = p;
309: unsigned long *t = *tt;
310: unsigned char c;
311: *d++ = *t >> 24;
312: *d++ = *t >> 16;
313: *d++ = *t >> 8;
314: *d++ = *t++;
315: *d++ = *t >> 8;
316: *d++ = *t++;
317: c = *t++ << 7;
318: c |= (*t++ & 0x03) << 5;
319: *d++ = c | (*t++ & 0x1F);
320: *d++ = *t >> 20;
321: *d++ = *t >> 12;
322: *d++ = *t >> 4;
323: c = *t++ << 4;
324: *d++ = c | (*t++ & 0x0F);
325: *tt = t;
326: return d;
327: }
328:
329: const static signed char syntax_cable_delivery_system[] = {
330: SYNTAX_DESCRTAG,
331: SYNTAX_NUMBER(frequency)
332: SYNTAX_NUMBER(fec_outer)
333: SYNTAX_NUMBER(modulation)
334: SYNTAX_NUMBER(symbol_rate)
335: SYNTAX_NUMBER(fec_inner),
336: SYNTAX_END
337: };
338:
339: static unsigned char *gen_cable_delivery_system(struct sitab *st,
340: unsigned char *p, unsigned long **tt)
341: {
342: unsigned char *d = p;
343: unsigned long *t = *tt;
344: unsigned char c;
345: *d++ = *t >> 24;
346: *d++ = *t >> 16;
347: *d++ = *t >> 8;
348: *d++ = *t++;
349: *d++ = 0xFF;
350: *d++ = 0xF0 | *t++;
351: *d++ = *t++;
352: *d++ = *t >> 20;
353: *d++ = *t >> 12;
354: *d++ = *t >> 4;
355: c = *t++ << 4;
356: *d++ = c | (*t++ & 0x0F);
357: *tt = t;
358: return d;
359: }
360:
361: const static signed char syntax_bouquet_name[] = {
362: SYNTAX_DESCRTAG,
363: SYNTAX_STRING,
364: SYNTAX_END
365: };
366:
367: static unsigned char *gen_bouquet_name(struct sitab *st, unsigned char *p,
368: unsigned long **tt)
369: {
370: unsigned char *d = p;
371: unsigned long *t = *tt;
372: int i;
373: i = *t++;
374: memcpy(d, t, i);
375: d += i;
376: t += (i + sizeof(long) - 1) / sizeof(long);
377: *tt = t;
378: return d;
379: }
380:
381: const static signed char syntax_service[] = {
382: SYNTAX_DESCRTAG,
383: SYNTAX_NUMBER(service_type),
384: SYNTAX_STRING,
385: SYNTAX_STRING,
386: SYNTAX_END
387: };
388:
389: static unsigned char *gen_service(struct sitab *st, unsigned char *p,
390: unsigned long **tt)
391: {
392: unsigned char *d = p;
393: unsigned long *t = *tt;
394: int i;
395: *d++ = *t++;
396: *d++ = i = *t++;
397: memcpy(d, t, i);
398: d += i;
399: t += (i + sizeof(long) - 1) / sizeof(long);
400: *d++ = i = *t++;
401: memcpy(d, t, i);
402: d += i;
403: t += (i + sizeof(long) - 1) / sizeof(long);
404: *tt = t;
405: return d;
406: }
407:
408: const static signed char syntax_country_availability[] = {
409: SYNTAX_DESCRTAG,
410: SYNTAX_NUMBER(country_availability_flag),
411: SYNTAX_LOOP,
412: SYNTAX_STRING,
413: SYNTAX_END
414: };
415:
416: static unsigned char *gen_country_availability(struct sitab *st,
417: unsigned char *p, unsigned long **tt)
418: {
419: unsigned char *d = p;
420: unsigned long *t = *tt;
421: int i, j;
422: *d++ = (*t++ << 7) | 0x7F;
423: i = *t++;
424: while (i > 0) {
425: j = *t++;
426: memcpy(d, t, 3);
427: d += 3;
428: t += (j + sizeof(long) - 1) / sizeof(long);
429: i -= 1;
430: }
431: *tt = t;
432: return d;
433: }
434:
435: const static signed char syntax_linkage[] = {
436: SYNTAX_DESCRTAG,
437: SYNTAX_NUMBER(transport_stream_id)
438: SYNTAX_NUMBER(original_network_id)
439: SYNTAX_NUMBER(service_id)
440: SYNTAX_NUMBER(linkage_type)
441: SYNTAX_NUMBER(hand_over_type)
442: SYNTAX_NUMBER(origin_type)
443: SYNTAX_NUMBER(network_id)
444: SYNTAX_NUMBER(initial_service_id),
445: SYNTAX_LOOP,
446: SYNTAX_NUMBER(private_data_byte),
447: SYNTAX_END
448: };
449:
450: static unsigned char *gen_linkage(struct sitab *st, unsigned char *p,
451: unsigned long **tt)
452: {
453: unsigned char *d = p;
454: unsigned long *t = *tt;
455: int i;
456: unsigned char l, h, o;
457: unsigned long n, s;
458: *d++ = *t >> 8;
459: *d++ = *t++;
460: *d++ = *t >> 8;
461: *d++ = *t++;
462: *d++ = *t >> 8;
463: *d++ = *t++;
464: *d++ = l = *t++;
465: h = *t++ & 0x0F;
466: o = *t++ & 0x01;
467: n = *t++;
468: s = *t++;
469: if (l == 8) {
470: *d++ = (h << 4) | 0x0E | o;
471: if ((h >= 1) && (h <= 3)) {
472: *d++ = n >> 8;
473: *d++ = n;
474: }
475: if (o == 0) {
476: *d++ = s >> 8;
477: *d++ = s;
478: }
479: }
480: i = *t++;
481: while (i > 0) {
482: *d++ = *t++;
483: i -= 1;
484: }
485: *tt = t;
486: return d;
487: }
488:
489: const static signed char syntax_nvod_reference[] = {
490: SYNTAX_DESCRTAG,
491: SYNTAX_LOOP,
492: SYNTAX_NUMBER(transport_stream_id)
493: SYNTAX_NUMBER(original_network_id)
494: SYNTAX_NUMBER(service_id),
495: SYNTAX_END
496: };
497:
498: static unsigned char *gen_nvod_reference(struct sitab *st, unsigned char *p,
499: unsigned long **tt)
500: {
501: unsigned char *d = p;
502: unsigned long *t = *tt;
503: int i;
504: i = *t++;
505: while (i > 0) {
506: *d++ = *t >> 8;
507: *d++ = *t++;
508: *d++ = *t >> 8;
509: *d++ = *t++;
510: *d++ = *t >> 8;
511: *d++ = *t++;
512: i -= 1;
513: }
514: *tt = t;
515: return d;
516: }
517:
518: const static signed char syntax_time_shifted_service[] = {
519: SYNTAX_DESCRTAG,
520: SYNTAX_NUMBER(reference_service_id),
521: SYNTAX_END
522: };
523:
524: static unsigned char *gen_time_shifted_service(struct sitab *st,
525: unsigned char *p, unsigned long **tt)
526: {
527: unsigned char *d = p;
528: unsigned long *t = *tt;
529: *d++ = *t >> 8;
530: *d++ = *t++;
531: *tt = t;
532: return d;
533: }
534:
535: const static signed char syntax_short_event[] = {
536: SYNTAX_DESCRTAG,
537: SYNTAX_STRING,
538: SYNTAX_STRING,
539: SYNTAX_STRING,
540: SYNTAX_END
541: };
542:
543: static unsigned char *gen_short_event(struct sitab *st, unsigned char *p,
544: unsigned long **tt)
545: {
546: unsigned char *d = p;
547: unsigned long *t = *tt;
548: int i;
549: i = *t++;
550: memcpy(d, t, 3);
551: d += 3;
552: t += (i + sizeof(long) - 1) / sizeof(long);
553: *d++ = i = *t++;
554: memcpy(d, t, i);
555: d += i;
556: t += (i + sizeof(long) - 1) / sizeof(long);
557: *d++ = i = *t++;
558: memcpy(d, t, i);
559: d += i;
560: t += (i + sizeof(long) - 1) / sizeof(long);
561: *tt = t;
562: return d;
563: }
564:
565: const static signed char syntax_extended_event[] = {
566: SYNTAX_DESCRTAG,
567: SYNTAX_STRING,
568: SYNTAX_LOOP,
569: SYNTAX_STRING,
570: SYNTAX_STRING,
571: SYNTAX_LOOPEND,
572: SYNTAX_STRING,
573: SYNTAX_END
574: };
575:
576: static unsigned char *gen_extended_event(struct sitab *st, unsigned char *p,
577: unsigned long **tt)
578: {
579: unsigned char *d = p;
580: unsigned long *t = *tt;
581: int i, j;
582: *d++ = (descrcnt[0x4E - DESCR_FIRST] << 4)
583: | (st->descrnum[0x4E - DESCR_FIRST] & 0x0F);
584: i = *t++;
585: memcpy(d, t, 3);
586: d += 4;
587: t += (i + sizeof(long) - 1) / sizeof(long);
588: i = *t++;
589: while (i > 0) {
590: *d++ = j = *t++;
591: memcpy(d, t, j);
592: d += j;
593: t += (j + sizeof(long) - 1) / sizeof(long);
594: *d++ = j = *t++;
595: memcpy(d, t, j);
596: d += j;
597: t += (j + sizeof(long) - 1) / sizeof(long);
598: i -= 1;
599: }
600: p[4] = d-p-5;
601: *d++ = i = *t++;
602: memcpy(d, t, i);
603: d += i;
604: t += (i + sizeof(long) - 1) / sizeof(long);
605: *tt = t;
606: return d;
607: }
608:
609: const static signed char syntax_time_shifted_event[] = {
610: SYNTAX_DESCRTAG,
611: SYNTAX_NUMBER(reference_service_id)
612: SYNTAX_NUMBER(reference_event_id),
613: SYNTAX_END
614: };
615:
616: static unsigned char *gen_time_shifted_event(struct sitab *st, unsigned char *p,
617: unsigned long **tt)
618: {
619: unsigned char *d = p;
620: unsigned long *t = *tt;
621: *d++ = *t >> 8;
622: *d++ = *t++;
623: *d++ = *t >> 8;
624: *d++ = *t++;
625: *tt = t;
626: return d;
627: }
628:
629: const static signed char syntax_component[] = {
630: SYNTAX_DESCRTAG,
631: SYNTAX_NUMBER(stream_content)
632: SYNTAX_NUMBER(component_type)
633: SYNTAX_NUMBER(component_tag),
634: SYNTAX_STRING,
635: SYNTAX_STRING,
636: SYNTAX_END
637: };
638:
639: static unsigned char *gen_component(struct sitab *st, unsigned char *p,
640: unsigned long **tt)
641: {
642: unsigned char *d = p;
643: unsigned long *t = *tt;
644: int i;
645: *d++ = 0xF0 | *t++;
646: *d++ = *t++;
647: *d++ = *t++;
648: i = *t++;
649: memcpy(d, t, 3);
650: d += 3;
651: t += (i + sizeof(long) - 1) / sizeof(long);
652: i = *t++;
653: memcpy(d, t, i);
654: d += i;
655: t += (i + sizeof(long) - 1) / sizeof(long);
656: *tt = t;
657: return d;
658: }
659:
660: const static signed char syntax_mosaic[] = {
661: SYNTAX_DESCRTAG,
662: SYNTAX_NUMBER(mosaic_entry_point)
663: SYNTAX_NUMBER(number_of_horizontal_elementary_cells)
664: SYNTAX_NUMBER(number_of_vertical_elementary_cells),
665: SYNTAX_LOOP,
666: SYNTAX_NUMBER(logical_cell_id)
667: SYNTAX_NUMBER(logical_cell_presentation_info),
668: SYNTAX_LOOP,
669: SYNTAX_NUMBER(elementary_cell_id),
670: SYNTAX_LOOPEND,
671: SYNTAX_NUMBER(cell_linkage_info)
672: SYNTAX_NUMBER(bouquet_id)
673: SYNTAX_NUMBER(original_network_id)
674: SYNTAX_NUMBER(transport_stream_id)
675: SYNTAX_NUMBER(service_id)
676: SYNTAX_NUMBER(event_id),
677: SYNTAX_END
678: };
679:
680: static unsigned char *gen_mosaic(struct sitab *st, unsigned char *p,
681: unsigned long **tt)
682: {
683: unsigned char *d = p;
684: unsigned long *t = *tt;
685: unsigned char *e;
686: unsigned char c;
687: int i, j;
688: c = *t++ << 7;
689: c = c | ((*t++ & 0x07) << 4);
690: *d++ = c | 0x08 | (*t++ & 0x07);
691: i = *t++;
692: while (i > 0) {
693: *d++ = (*t++ << 2) | 0x03;
694: *d++ = 0xF8 | *t++;
695: e = d++;
696: j = *t++;
697: while (j > 0) {
698: *d++ = 0xC0 | *t++;
699: j -= 1;
700: }
701: *e = d-e-1;
702: switch (*d++ = *t++) {
703: case 0x01:
704: *d++ = t[0] >> 8;
705: *d++ = t[0];
706: break;
707: case 0x02:
708: case 0x03:
709: *d++ = t[1] >> 8;
710: *d++ = t[1];
711: *d++ = t[2] >> 8;
712: *d++ = t[2];
713: *d++ = t[3] >> 8;
714: *d++ = t[3];
715: break;
716: case 0x04:
717: *d++ = t[1] >> 8;
718: *d++ = t[1];
719: *d++ = t[2] >> 8;
720: *d++ = t[2];
721: *d++ = t[3] >> 8;
722: *d++ = t[3];
723: *d++ = t[4] >> 8;
724: *d++ = t[4];
725: break;
726: }
727: t += 5;
728: i -= 1;
729: }
730: *tt = t;
731: return d;
732: }
733:
734: const static signed char syntax_ca_identifier[] = {
735: SYNTAX_DESCRTAG,
736: SYNTAX_LOOP,
737: SYNTAX_NUMBER(ca_system_id),
738: SYNTAX_END
739: };
740:
741: static unsigned char *gen_ca_identifier(struct sitab *st, unsigned char *p,
742: unsigned long **tt)
743: {
744: unsigned char *d = p;
745: unsigned long *t = *tt;
746: int i;
747: i = *t++;
748: while (i > 0) {
749: *d++ = *t >> 8;
750: *d++ = *t++;
751: i -= 1;
752: }
753: *tt = t;
754: return d;
755: }
756:
757: const static signed char syntax_content[] = {
758: SYNTAX_DESCRTAG,
759: SYNTAX_LOOP,
760: SYNTAX_NUMBER(content_nibbles)
761: SYNTAX_NUMBER(user_nibbles),
762: SYNTAX_END
763: };
764:
765: static unsigned char *gen_content(struct sitab *st, unsigned char *p,
766: unsigned long **tt)
767: {
768: unsigned char *d = p;
769: unsigned long *t = *tt;
770: int i;
771: i = *t++;
772: while (i > 0) {
773: *d++ = *t++;
774: *d++ = *t++;
775: i -= 1;
776: }
777: *tt = t;
778: return d;
779: }
780:
781: const static signed char syntax_parental_rating[] = {
782: SYNTAX_DESCRTAG,
783: SYNTAX_STRING,
784: SYNTAX_NUMBER(rating),
785: SYNTAX_END
786: };
787:
788: static unsigned char *gen_parental_rating(struct sitab *st, unsigned char *p,
789: unsigned long **tt)
790: {
791: unsigned char *d = p;
792: unsigned long *t = *tt;
793: int i, j;
794: i = *t++;
795: while (i > 0) {
796: j = *t++;
797: memcpy(d, t, 3);
798: d += 3;
799: t += (j + sizeof(long) - 1) / sizeof(long);
800: *d++ = *t++;
801: i -= 1;
802: }
803: *tt = t;
804: return d;
805: }
806:
807: const static signed char syntax_telephone[] = {
808: SYNTAX_DESCRTAG,
809: SYNTAX_NUMBER(foreign_availability)
810: SYNTAX_NUMBER(connection_type),
811: SYNTAX_STRING,
812: SYNTAX_STRING,
813: SYNTAX_STRING,
814: SYNTAX_STRING,
815: SYNTAX_STRING,
816: SYNTAX_END
817: };
818:
819: static unsigned char *gen_telephone(struct sitab *st, unsigned char *p,
820: unsigned long **tt)
821: {
822: unsigned char *d = p;
823: unsigned long *t = *tt;
824: unsigned char c;
825: int i;
826: c = *t++ << 5;
827: *d = 0xC0 | c | (*t++ & 0x1F);
828: d += 3;
829: i = *t++;
830: c = i << 5;
831: memcpy(d, t, i);
832: d += i;
833: t += (i + sizeof(long) - 1) / sizeof(long);
834: i = *t++;
835: c |= (i & 0x07) << 2;
836: memcpy(d, t, i);
837: d += i;
838: t += (i + sizeof(long) - 1) / sizeof(long);
839: i = *t++;
840: p[1] = 0x80 | c | (i & 0x03);
841: memcpy(d, t, i);
842: d += i;
843: t += (i + sizeof(long) - 1) / sizeof(long);
844: i = *t++;
845: c = i << 4;
846: memcpy(d, t, i);
847: d += i;
848: t += (i + sizeof(long) - 1) / sizeof(long);
849: i = *t++;
850: p[2] = 0x80 | c | (i & 0x0F);
851: memcpy(d, t, i);
852: d += i;
853: t += (i + sizeof(long) - 1) / sizeof(long);
854: *tt = t;
855: return d;
856: }
857:
858: const static signed char syntax_local_time_offset[] = {
859: SYNTAX_DESCRTAG,
860: SYNTAX_LOOP,
861: SYNTAX_STRING,
862: SYNTAX_NUMBER(country_region)
863: SYNTAX_NUMBER(local_time_offset_polarity)
864: SYNTAX_NUMBER(local_time_offset),
865: SYNTAX_DATETIME,
866: SYNTAX_NUMBER(next_time_offset),
867: SYNTAX_END
868: };
869:
870: static unsigned char *gen_local_time_offset(struct sitab *st, unsigned char *p,
871: unsigned long **tt)
872: {
873: unsigned char *d = p;
874: unsigned long *t = *tt;
875: unsigned char c;
876: int i, j;
877: i = *t++;
878: while (i > 0) {
879: j = *t++;
880: memcpy(d, t, 3);
881: d += 3;
882: t += (j + sizeof(long) - 1) / sizeof(long);
883: c = *t++ << 2;
884: *d++ = c | 0x02 | (*t++ & 0x01);
885: *d++ = *t >> 8;
886: *d++ = *t++;
887: *d++ = *t >> 8;
888: *d++ = *t++;
889: *d++ = *t >> 16;
890: *d++ = *t >> 8;
891: *d++ = *t++;
892: *d++ = *t >> 8;
893: *d++ = *t++;
894: i -= 1;
895: }
896: *tt = t;
897: return d;
898: }
899:
900: const static signed char syntax_terrestrial_delivery_system[] = {
901: SYNTAX_DESCRTAG,
902: SYNTAX_NUMBER(centre_frequency)
903: SYNTAX_NUMBER(bandwidth)
904: SYNTAX_NUMBER(constellation)
905: SYNTAX_NUMBER(hierarchy_information)
906: SYNTAX_NUMBER(code_rate_hp_stream)
907: SYNTAX_NUMBER(code_rate_lp_stream)
908: SYNTAX_NUMBER(guard_interval)
909: SYNTAX_NUMBER(transmission_mode)
910: SYNTAX_NUMBER(other_frequency_flag),
911: SYNTAX_END
912: };
913:
914: static unsigned char *gen_terrestrial_delivery_system(struct sitab *st,
915: unsigned char *p, unsigned long **tt)
916: {
917: unsigned char *d = p;
918: unsigned long *t = *tt;
919: unsigned char c;
920: *d++ = *t >> 24;
921: *d++ = *t >> 16;
922: *d++ = *t >> 8;
923: *d++ = *t++;
924: *d++ = (*t++ << 5) | 0x1F;
925: c = *t++ << 6;
926: c |= (*t++ & 0x07) << 3;
927: *d++ = c | (*t++ & 0x07);
928: c = *t++ << 5;
929: c |= (*t++ & 0x03) << 3;
930: c |= (*t++ & 0x03) << 1;
931: *d++ = c | (*t++ & 0x01);
932: *d++ = 0xFF;
933: *d++ = 0xFF;
934: *d++ = 0xFF;
935: *d++ = 0xFF;
936: *tt = t;
937: return d;
938: }
939:
940: const static signed char syntax_multilingual_network_name[] = {
941: SYNTAX_DESCRTAG,
942: SYNTAX_LOOP,
943: SYNTAX_STRING,
944: SYNTAX_STRING,
945: SYNTAX_END
946: };
947:
948: static unsigned char *gen_multilingual_network_name(struct sitab *st,
949: unsigned char *p, unsigned long **tt)
950: {
951: unsigned char *d = p;
952: unsigned long *t = *tt;
953: int i, j;
954: i = *t++;
955: while (i > 0) {
956: j = *t++;
957: memcpy(d, t, 3);
958: d += 3;
959: t += (j + sizeof(long) - 1) / sizeof(long);
960: *d++ = j = *t++;
961: memcpy(d, t, j);
962: d += j;
963: t += (j + sizeof(long) - 1) / sizeof(long);
964: i -= 1;
965: }
966: *tt = t;
967: return d;
968: }
969:
970: const static signed char syntax_multilingual_bouquet_name[] = {
971: SYNTAX_DESCRTAG,
972: SYNTAX_LOOP,
973: SYNTAX_STRING,
974: SYNTAX_STRING,
975: SYNTAX_END
976: };
977:
978: static unsigned char *gen_multilingual_bouquet_name(struct sitab *st,
979: unsigned char *p, unsigned long **tt)
980: {
981: unsigned char *d = p;
982: unsigned long *t = *tt;
983: int i, j;
984: i = *t++;
985: while (i > 0) {
986: j = *t++;
987: memcpy(d, t, 3);
988: d += 3;
989: t += (j + sizeof(long) - 1) / sizeof(long);
990: *d++ = j = *t++;
991: memcpy(d, t, j);
992: d += j;
993: t += (j + sizeof(long) - 1) / sizeof(long);
994: i -= 1;
995: }
996: *tt = t;
997: return d;
998: }
999:
1000: const static signed char syntax_multilingual_service_name[] = {
1001: SYNTAX_DESCRTAG,
1002: SYNTAX_LOOP,
1003: SYNTAX_STRING,
1004: SYNTAX_STRING,
1005: SYNTAX_STRING,
1006: SYNTAX_END
1007: };
1008:
1009: static unsigned char *gen_multilingual_service_name(struct sitab *st,
1010: unsigned char *p, unsigned long **tt)
1011: {
1012: unsigned char *d = p;
1013: unsigned long *t = *tt;
1014: int i, j;
1015: i = *t++;
1016: while (i > 0) {
1017: j = *t++;
1018: memcpy(d, t, 3);
1019: d += 3;
1020: t += (j + sizeof(long) - 1) / sizeof(long);
1021: *d++ = j = *t++;
1022: memcpy(d, t, j);
1023: d += j;
1024: t += (j + sizeof(long) - 1) / sizeof(long);
1025: *d++ = j = *t++;
1026: memcpy(d, t, j);
1027: d += j;
1028: t += (j + sizeof(long) - 1) / sizeof(long);
1029: i -= 1;
1030: }
1031: *tt = t;
1032: return d;
1033: }
1034:
1035: const static signed char syntax_multilingual_component[] = {
1036: SYNTAX_DESCRTAG,
1037: SYNTAX_NUMBER(component_tag),
1038: SYNTAX_LOOP,
1039: SYNTAX_STRING,
1040: SYNTAX_STRING,
1041: SYNTAX_END
1042: };
1043:
1044: static unsigned char *gen_multilingual_component(struct sitab *st,
1045: unsigned char *p, unsigned long **tt)
1046: {
1047: unsigned char *d = p;
1048: unsigned long *t = *tt;
1049: int i, j;
1050: *d++ = *t++;
1051: i = *t++;
1052: while (i > 0) {
1053: j = *t++;
1054: memcpy(d, t, 3);
1055: d += 3;
1056: t += (j + sizeof(long) - 1) / sizeof(long);
1057: *d++ = j = *t++;
1058: memcpy(d, t, j);
1059: d += j;
1060: t += (j + sizeof(long) - 1) / sizeof(long);
1061: i -= 1;
1062: }
1063: *tt = t;
1064: return d;
1065: }
1066:
1067: const static signed char syntax_private_data_specifier[] = {
1068: SYNTAX_DESCRTAG,
1069: SYNTAX_NUMBER(private_data_specifier),
1070: SYNTAX_END
1071: };
1072:
1073: static unsigned char *gen_private_data_specifier(struct sitab *st,
1074: unsigned char *p, unsigned long **tt)
1075: {
1076: unsigned char *d = p;
1077: unsigned long *t = *tt;
1078: *d++ = *t >> 24;
1079: *d++ = *t >> 16;
1080: *d++ = *t >> 8;
1081: *d++ = *t++;
1082: *tt = t;
1083: return d;
1084: }
1085:
1086: const static signed char syntax_short_smoothing_buffer[] = {
1087: SYNTAX_DESCRTAG,
1088: SYNTAX_NUMBER(sb_size)
1089: SYNTAX_NUMBER(sb_leak_rate),
1090: SYNTAX_END
1091: };
1092:
1093: static unsigned char *gen_short_smoothing_buffer(struct sitab *st,
1094: unsigned char *p, unsigned long **tt)
1095: {
1096: unsigned char *d = p;
1097: unsigned long *t = *tt;
1098: unsigned char c;
1099: c = *t++ << 6;
1100: *d++ = c | (*t++ & 0x3F);
1101: *tt = t;
1102: return d;
1103: }
1104:
1105: const static signed char syntax_frequency_list[] = {
1106: SYNTAX_DESCRTAG,
1107: SYNTAX_NUMBER(coding_type),
1108: SYNTAX_LOOP,
1109: SYNTAX_NUMBER(centre_frequency),
1110: SYNTAX_END
1111: };
1112:
1113: static unsigned char *gen_frequency_list(struct sitab *st, unsigned char *p,
1114: unsigned long **tt)
1115: {
1116: unsigned char *d = p;
1117: unsigned long *t = *tt;
1118: int i;
1119: *d++ = 0xFC | *t++;
1120: i = *t++;
1121: while (i > 0) {
1122: *d++ = *t >> 24;
1123: *d++ = *t >> 16;
1124: *d++ = *t >> 8;
1125: *d++ = *t++;
1126: i -= 1;
1127: }
1128: *tt = t;
1129: return d;
1130: }
1131:
1132: const static signed char syntax_partial_transport_stream[] = {
1133: SYNTAX_DESCRTAG,
1134: SYNTAX_NUMBER(peak_rate)
1135: SYNTAX_NUMBER(minimum_overall_smoothing_rate)
1136: SYNTAX_NUMBER(maximum_overall_smoothing_buffer),
1137: SYNTAX_END
1138: };
1139:
1140: static unsigned char *gen_partial_transport_stream(struct sitab *st,
1141: unsigned char *p, unsigned long **tt)
1142: {
1143: unsigned char *d = p;
1144: unsigned long *t = *tt;
1145: *d++ = 0xC0 | (*t >> 16);
1146: *d++ = *t >> 8;
1147: *d++ = *t++;
1148: *d++ = 0xC0 | (*t >> 16);
1149: *d++ = *t >> 8;
1150: *d++ = *t++;
1151: *d++ = 0xC0 | (*t >> 8);
1152: *d++ = *t++;
1153: *tt = t;
1154: return d;
1155: }
1156:
1157: const static signed char syntax_data_broadcast[] = {
1158: SYNTAX_DESCRTAG,
1159: SYNTAX_NUMBER(data_broadcast_id)
1160: SYNTAX_NUMBER(component_tag),
1161: SYNTAX_LOOP,
1162: SYNTAX_NUMBER(selector_byte),
1163: SYNTAX_LOOPEND,
1164: SYNTAX_STRING,
1165: SYNTAX_STRING,
1166: SYNTAX_END
1167: };
1168:
1169: static unsigned char *gen_data_broadcast(struct sitab *st, unsigned char *p,
1170: unsigned long **tt)
1171: {
1172: unsigned char *d = p;
1173: unsigned long *t = *tt;
1174: int i;
1175: *d++ = *t >> 8;
1176: *d++ = *t++;
1177: *d++ = *t++;
1178: *d++ = i = *t++;
1179: while (i > 0) {
1180: *d++ = *t++;
1181: i -= 1;
1182: }
1183: i = *t++;
1184: memcpy(d, t, 3);
1185: d += 3;
1186: t += (i + sizeof(long) - 1) / sizeof(long);
1187: *d++ = i = *t++;
1188: memcpy(d, t, i);
1189: d += i;
1190: t += (i + sizeof(long) - 1) / sizeof(long);
1191: *tt = t;
1192: return d;
1193: }
1194:
1195: const static signed char syntax_pdc[] = {
1196: SYNTAX_DESCRTAG,
1197: SYNTAX_NUMBER(program_identification_label),
1198: SYNTAX_END
1199: };
1200:
1201: static unsigned char *gen_pdc(struct sitab *st, unsigned char *p,
1202: unsigned long **tt)
1203: {
1204: unsigned char *d = p;
1205: unsigned long *t = *tt;
1206: *d++ = 0xF0 | (*t >> 16);
1207: *d++ = *t >> 8;
1208: *d++ = *t++;
1209: *tt = t;
1210: return d;
1211: }
1212:
1213: const static signed char syntax_cell_list[] = {
1214: SYNTAX_DESCRTAG,
1215: SYNTAX_LOOP,
1216: SYNTAX_NUMBER(cell_id)
1217: SYNTAX_NUMBER(cell_latitude)
1218: SYNTAX_NUMBER(cell_longitude)
1219: SYNTAX_NUMBER(cell_extend_of_latitude)
1220: SYNTAX_NUMBER(cell_extend_of_longitude),
1221: SYNTAX_LOOP,
1222: SYNTAX_NUMBER(cell_id_extension)
1223: SYNTAX_NUMBER(subcell_latitude)
1224: SYNTAX_NUMBER(subcell_longitude)
1225: SYNTAX_NUMBER(subcell_extend_of_latitude)
1226: SYNTAX_NUMBER(subcell_extend_of_longitude),
1227: SYNTAX_END
1228: };
1229:
1230: static unsigned char *gen_cell_list(struct sitab *st, unsigned char *p,
1231: unsigned long **tt)
1232: {
1233: unsigned char *d = p;
1234: unsigned long *t = *tt;
1235: unsigned char c;
1236: int i, j;
1237: i = *t++;
1238: while (i > 0) {
1239: *d++ = *t >> 8;
1240: *d++ = *t++;
1241: *d++ = *t >> 8;
1242: *d++ = *t++;
1243: *d++ = *t >> 8;
1244: *d++ = *t++;
1245: *d++ = *t >> 4;
1246: c = *t++ << 4;
1247: *d++ = c | ((*t >> 8) & 0x0F);
1248: *d++ = *t++;
1249: j = *t++;
1250: *d++ = 8 * j;
1251: while (j > 0) {
1252: *d++ = *t++;
1253: *d++ = *t >> 8;
1254: *d++ = *t++;
1255: *d++ = *t >> 8;
1256: *d++ = *t++;
1257: *d++ = *t >> 4;
1258: c = *t++ << 4;
1259: *d++ = c | ((*t >> 8) & 0x0F);
1260: *d++ = *t++;
1261: j -= 1;
1262: }
1263: i -= 1;
1264: }
1265: *tt = t;
1266: return d;
1267: }
1268:
1269: const static signed char syntax_cell_frequency_link[] = {
1270: SYNTAX_DESCRTAG,
1271: SYNTAX_LOOP,
1272: SYNTAX_NUMBER(cell_id)
1273: SYNTAX_NUMBER(frequency),
1274: SYNTAX_LOOP,
1275: SYNTAX_NUMBER(cell_id_extension)
1276: SYNTAX_NUMBER(transposer_frequency),
1277: SYNTAX_END
1278: };
1279:
1280: static unsigned char *gen_cell_frequency_link(struct sitab *st,
1281: unsigned char *p, unsigned long **tt)
1282: {
1283: unsigned char *d = p;
1284: unsigned long *t = *tt;
1285: int i, j;
1286: i = *t++;
1287: while (i > 0) {
1288: *d++ = *t >> 8;
1289: *d++ = *t++;
1290: *d++ = *t >> 24;
1291: *d++ = *t >> 16;
1292: *d++ = *t >> 8;
1293: *d++ = *t++;
1294: j = *t++;
1295: *d++ = 5 * j;
1296: while (j > 0) {
1297: *d++ = *t++;
1298: *d++ = *t >> 24;
1299: *d++ = *t >> 16;
1300: *d++ = *t >> 8;
1301: *d++ = *t++;
1302: j -= 1;
1303: }
1304: i -= 1;
1305: }
1306: *tt = t;
1307: return d;
1308: }
1309:
1310: const static signed char syntax_announcement_support[] = {
1311: SYNTAX_DESCRTAG,
1312: SYNTAX_NUMBER(announcement_support_indicator),
1313: SYNTAX_LOOP,
1314: SYNTAX_NUMBER(announcement_type)
1315: SYNTAX_NUMBER(reference_type)
1316: SYNTAX_NUMBER(original_network_id)
1317: SYNTAX_NUMBER(transport_stream_id)
1318: SYNTAX_NUMBER(service_id)
1319: SYNTAX_NUMBER(component_tag),
1320: SYNTAX_END
1321: };
1322:
1323: static unsigned char *gen_announcement_support(struct sitab *st,
1324: unsigned char *p, unsigned long **tt)
1325: {
1326: unsigned char *d = p;
1327: unsigned long *t = *tt;
1328: unsigned char c, v;
1329: int i;
1330: *d++ = *t >> 8;
1331: *d++ = *t++;
1332: i = *t++;
1333: while (i > 0) {
1334: c = *t++ << 4;
1335: v = *t++ & 0x07;
1336: *d++ = c | 0x08 | v;
1337: switch (v) {
1338: case 0x01:
1339: case 0x02:
1340: case 0x03:
1341: *d++ = *t >> 8;
1342: *d++ = *t++;
1343: *d++ = *t >> 8;
1344: *d++ = *t++;
1345: *d++ = *t >> 8;
1346: *d++ = *t++;
1347: *d++ = *t++;
1348: break;
1349: }
1350: i -= 1;
1351: }
1352: *tt = t;
1353: return d;
1354: }
1355:
1356: const static signed char *const descr_syntax[DESCR_LAST-DESCR_FIRST+1] = {
1357: &syntax_network_name[0],
1358: &syntax_service_list[0],
1359: NULL,
1360: &syntax_satellite_delivery_system[0],
1361: &syntax_cable_delivery_system[0],
1362: NULL,
1363: NULL,
1364: &syntax_bouquet_name[0],
1365: &syntax_service[0],
1366: &syntax_country_availability[0],
1367: &syntax_linkage[0],
1368: &syntax_nvod_reference[0],
1369: &syntax_time_shifted_service[0],
1370: &syntax_short_event[0],
1371: &syntax_extended_event[0],
1372: &syntax_time_shifted_event[0],
1373: &syntax_component[0],
1374: &syntax_mosaic[0],
1375: NULL,
1376: &syntax_ca_identifier[0],
1377: &syntax_content[0],
1378: &syntax_parental_rating[0],
1379: NULL,
1380: &syntax_telephone[0],
1381: &syntax_local_time_offset[0],
1382: NULL,
1383: &syntax_terrestrial_delivery_system[0],
1384: &syntax_multilingual_network_name[0],
1385: &syntax_multilingual_bouquet_name[0],
1386: &syntax_multilingual_service_name[0],
1387: &syntax_multilingual_component[0],
1388: &syntax_private_data_specifier[0],
1389: NULL,
1390: &syntax_short_smoothing_buffer[0],
1391: &syntax_frequency_list[0],
1392: &syntax_partial_transport_stream[0],
1393: &syntax_data_broadcast[0],
1394: NULL,
1395: NULL,
1396: NULL,
1397: NULL,
1398: &syntax_pdc[0],
1399: NULL,
1400: NULL,
1401: &syntax_cell_list[0],
1402: &syntax_cell_frequency_link[0],
1403: &syntax_announcement_support[0]
1404: };
1405:
1406: static unsigned char *gendescr(struct sitab *st, unsigned char *p,
1407: unsigned long **tt, unsigned char msb)
1408: {
1409: unsigned char *d = p+2;
1410: unsigned long *t = *tt;
1411: unsigned char *b;
1412: unsigned char v;
1413: int i;
1414: i = *t++;
1415: while (i > 0) {
1416: b = d+2;
1417: switch (*d = v = *t++) {
1418: case 0x40: d = gen_network_name(st, b, &t); break;
1419: case 0x41: d = gen_service_list(st, b, &t); break;
1420: case 0x43: d = gen_satellite_delivery_system(st, b, &t); break;
1421: case 0x44: d = gen_cable_delivery_system(st, b, &t); break;
1422: case 0x47: d = gen_bouquet_name(st, b, &t); break;
1423: case 0x48: d = gen_service(st, b, &t); break;
1424: case 0x49: d = gen_country_availability(st, b, &t); break;
1425: case 0x4A: d = gen_linkage(st, b, &t); break;
1426: case 0x4B: d = gen_nvod_reference(st, b, &t); break;
1427: case 0x4C: d = gen_time_shifted_service(st, b, &t); break;
1428: case 0x4D: d = gen_short_event(st, b, &t); break;
1429: case 0x4E: d = gen_extended_event(st, b, &t); break;
1430: case 0x4F: d = gen_time_shifted_event(st, b, &t); break;
1431: case 0x50: d = gen_component(st, b, &t); break;
1432: case 0x51: d = gen_mosaic(st, b, &t); break;
1433: case 0x53: d = gen_ca_identifier(st, b, &t); break;
1434: case 0x54: d = gen_content(st, b, &t); break;
1435: case 0x55: d = gen_parental_rating(st, b, &t); break;
1436: case 0x57: d = gen_telephone(st, b, &t); break;
1437: case 0x58: d = gen_local_time_offset(st, b, &t); break;
1438: case 0x5A: d = gen_terrestrial_delivery_system(st, b, &t); break;
1439: case 0x5B: d = gen_multilingual_network_name(st, b, &t); break;
1440: case 0x5C: d = gen_multilingual_bouquet_name(st, b, &t); break;
1441: case 0x5D: d = gen_multilingual_service_name(st, b, &t); break;
1442: case 0x5E: d = gen_multilingual_component(st, b, &t); break;
1443: case 0x5F: d = gen_private_data_specifier(st, b, &t); break;
1444: case 0x61: d = gen_short_smoothing_buffer(st, b, &t); break;
1445: case 0x62: d = gen_frequency_list(st, b, &t); break;
1446: case 0x63: d = gen_partial_transport_stream(st, b, &t); break;
1447: case 0x64: d = gen_data_broadcast(st, b, &t); break;
1448: case 0x69: d = gen_pdc(st, b, &t); break;
1449: case 0x6C: d = gen_cell_list(st, b, &t); break;
1450: case 0x6D: d = gen_cell_frequency_link(st, b, &t); break;
1451: case 0x6E: d = gen_announcement_support(st, b, &t); break;
1452: default:
1453: fprintf(stderr, "error: descr not implemented (%02x)\n", *d);
1454: exit(1);
1455: }
1456: descrcnt[v-DESCR_FIRST] += 1;
1457: b[-1] = d-b;
1458: i -= 1;
1459: }
1460: i = d-p-2;
1461: p[0] = msb | (i >> 8);
1462: p[1] = i;
1463: *tt = t;
1464: return d;
1465: }
1466:
1467: const static signed char syntax_nit[] = {
1468: SYNTAX_NUMBER(network_id),
1469: SYNTAX_DESCR,
1470: SYNTAX_LOOP,
1471: SYNTAX_NUMBER(transport_stream_id)
1472: SYNTAX_NUMBER(original_network_id),
1473: SYNTAX_DESCR,
1474: SYNTAX_END
1475: };
1476:
1477: static int gentab_nit(struct sitab *st, unsigned char *b)
1478: {
1479: unsigned char *p = b;
1480: unsigned long *t = st->tab;
1481: unsigned char *q;
1482: int i;
1483: *p = st->tableid;
1484: p += 3;
1485: *p++ = *t >> 8;
1486: *p++ = *t++;
1487: *p++ = 0xC0 | (st->version << 1) | 0x01;
1488: *p++ = 0;
1489: *p++ = 0;
1490: p = gendescr(st, p, &t, 0xF0);
1491: q = p;
1492: p += 2;
1493: i = *t++;
1494: while (i > 0) {
1495: *p++ = *t >> 8;
1496: *p++ = *t++;
1497: *p++ = *t >> 8;
1498: *p++ = *t++;
1499: p = gendescr(st, p, &t, 0xF0);
1500: i -= 1;
1501: }
1502: i = p-q-2;
1503: q[0] = 0xF0 | (i >> 8);
1504: q[1] = i;
1505: i = p-b+1;
1506: b[1] = 0xF0 | (i >> 8);
1507: b[2] = i;
1508: crc32_calc(b, i-1, p);
1509: return p-b+4;
1510: }
1511:
1512: const static signed char syntax_sdt[] = {
1513: SYNTAX_NUMBER(transport_stream_id)
1514: SYNTAX_NUMBER(original_network_id),
1515: SYNTAX_LOOP,
1516: SYNTAX_NUMBER(service_id)
1517: SYNTAX_NUMBER(eit_schedule_flag)
1518: SYNTAX_NUMBER(eit_present_following_flag)
1519: SYNTAX_NUMBER(running_status),
1520: SYNTAX_DESCR,
1521: SYNTAX_END
1522: };
1523:
1524: static int gentab_sdt(struct sitab *st, unsigned char *b)
1525: {
1526: unsigned char *p = b;
1527: unsigned long *t = st->tab;
1528: int i;
1529: unsigned char c;
1530: *p = st->tableid;
1531: p += 3;
1532: *p++ = *t >> 8;
1533: *p++ = *t++;
1534: *p++ = 0xC0 | (st->version << 1) | 0x01;
1535: *p++ = 0;
1536: *p++ = 0;
1537: *p++ = *t >> 8;
1538: *p++ = *t++;
1539: *p++ = 0xFF;
1540: i = *t++;
1541: while (i > 0) {
1542: *p++ = *t >> 8;
1543: *p++ = *t++;
1544: c = *t++ << 1;
1545: *p++ = 0xFC | c | (*t++ & 1);
1546: c = *t++ << 5;
1547: p = gendescr(st, p, &t, c);
1548: i -= 1;
1549: }
1550: i = p-b+1;
1551: b[1] = 0xF0 | (i >> 8);
1552: b[2] = i;
1553: crc32_calc(b, i-1, p);
1554: return p-b+4;
1555: }
1556:
1557: const static signed char syntax_bat[] = {
1558: SYNTAX_NUMBER(bouquet_id),
1559: SYNTAX_DESCR,
1560: SYNTAX_LOOP,
1561: SYNTAX_NUMBER(transport_stream_id)
1562: SYNTAX_NUMBER(original_network_id),
1563: SYNTAX_DESCR,
1564: SYNTAX_END
1565: };
1566:
1567: static int gentab_bat(struct sitab *st, unsigned char *b)
1568: {
1569: unsigned char *p = b;
1570: unsigned long *t = st->tab;
1571: unsigned char *q;
1572: int i;
1573: *p = st->tableid;
1574: p += 3;
1575: *p++ = *t >> 8;
1576: *p++ = *t++;
1577: *p++ = 0xC0 | (st->version << 1) | 0x01;
1578: *p++ = 0;
1579: *p++ = 0;
1580: p = gendescr(st, p, &t, 0xF0);
1581: q = p;
1582: p += 2;
1583: i = *t++;
1584: while (i > 0) {
1585: *p++ = *t >> 8;
1586: *p++ = *t++;
1587: *p++ = *t >> 8;
1588: *p++ = *t++;
1589: p = gendescr(st, p, &t, 0xF0);
1590: i -= 1;
1591: }
1592: i = p-q-2;
1593: q[0] = 0xF0 | (i >> 8);
1594: q[1] = i;
1595: i = p-b+1;
1596: b[1] = 0xF0 | (i >> 8);
1597: b[2] = i;
1598: crc32_calc(b, i-1, p);
1599: return p-b+4;
1600: }
1601:
1602: const static signed char syntax_eit[] = {
1603: SYNTAX_NUMBER(service_id)
1604: SYNTAX_NUMBER(transport_stream_id)
1605: SYNTAX_NUMBER(original_network_id),
1606: SYNTAX_LOOP,
1607: SYNTAX_NUMBER(event_id),
1608: SYNTAX_DATETIME,
1609: SYNTAX_NUMBER(duration)
1610: SYNTAX_NUMBER(running_status),
1611: SYNTAX_DESCR,
1612: SYNTAX_END
1613: };
1614:
1615: static int gentab_eit(struct sitab *st, unsigned char *b)
1616: {
1617: unsigned char *p = b;
1618: unsigned long *t = st->tab;
1619: int i;
1620: struct sitab *gt;
1621: *p = i = st->tableid;
1622: p += 3;
1623: *p++ = *t >> 8;
1624: *p++ = *t++;
1625: *p++ = 0xC0 | (st->version << 1) | 0x01;
1626: *p++ = 0;
1627: *p++ = 0;
1628: *p++ = *t >> 8;
1629: *p++ = *t++;
1630: *p++ = *t >> 8;
1631: *p++ = *t++;
1632: *p++ = 0;
1633: gt = runtab;
1634: while (gt != NULL) {
1635: if ((gt->esi == eit) && (gt->tableid > i)) {
1636: i = gt->tableid;
1637: }
1638: gt = gt->next;
1639: }
1640: *p++ = i;
1641: i = *t++;
1642: *p++ = *t >> 8;
1643: *p++ = *t++;
1644: *p++ = *t >> 8;
1645: *p++ = *t++;
1646: *p++ = *t >> 16;
1647: *p++ = *t >> 8;
1648: *p++ = *t++;
1649: *p++ = *t >> 16;
1650: *p++ = *t >> 8;
1651: *p++ = *t++;
1652: i = *t++ << 5;
1653: p = gendescr(st, p, &t, i);
1654: i = p-b+1;
1655: b[1] = 0xF0 | (i >> 8);
1656: b[2] = i;
1657: crc32_calc(b, i-1, p);
1658: return p-b+4;
1659: }
1660:
1661: const static signed char syntax_rst[] = {
1662: SYNTAX_LOOP,
1663: SYNTAX_NUMBER(transport_stream_id)
1664: SYNTAX_NUMBER(original_network_id)
1665: SYNTAX_NUMBER(service_id)
1666: SYNTAX_NUMBER(event_id)
1667: SYNTAX_NUMBER(running_status),
1668: SYNTAX_END
1669: };
1670:
1671: static int gentab_rst(struct sitab *st, unsigned char *b)
1672: {
1673: unsigned char *p = b;
1674: unsigned long *t = st->tab;
1675: int i;
1676: *p = st->tableid;
1677: p += 3;
1678: i = *t++;
1679: while (i > 0) {
1680: *p++ = *t >> 8;
1681: *p++ = *t++;
1682: *p++ = *t >> 8;
1683: *p++ = *t++;
1684: *p++ = *t >> 8;
1685: *p++ = *t++;
1686: *p++ = *t >> 8;
1687: *p++ = *t++;
1688: *p++ = 0xF8 | *t++;
1689: i -= 1;
1690: }
1691: i = p-b-3;
1692: b[1] = 0xF0 | (i >> 8);
1693: b[2] = i;
1694: return p-b;
1695: }
1696:
1697: static unsigned char *gentvdatetime(unsigned char *p, struct timeval *tv)
1698: {
1699: unsigned long d, s;
1700: s = tv->tv_sec;
1701: d = s / 86400;
1702: s = s % 86400;
1703: d += 40587;
1704: *p++ = d >> 8;
1705: *p++ = d;
1706: d = s / 3600;
1707: s = s % 3600;
1708: d += (d / 10) * 6;
1709: *p++ = d;
1710: d = s / 60;
1711: s = s % 60;
1712: d += (d / 10) * 6;
1713: *p++ = d;
1714: s += (s / 10) * 6;
1715: *p++ = s;
1716: return p;
1717: }
1718:
1719: const static signed char syntax_tdt[] = {
1720: SYNTAX_END
1721: };
1722:
1723: static int gentab_tdt(struct sitab *st, unsigned char *b, struct timeval *tv)
1724: {
1725: unsigned char *p = b;
1726: *p++ = st->tableid;
1727: *p++ = 0xF0;
1728: *p++ = 0x05;
1729: p = gentvdatetime(p, tv);
1730: return p-b;
1731: }
1732:
1733: const static signed char syntax_tot[] = {
1734: SYNTAX_DESCR,
1735: SYNTAX_END
1736: };
1737:
1738: static int gentab_tot(struct sitab *st, unsigned char *b, struct timeval *tv)
1739: {
1740: unsigned char *p = b;
1741: unsigned long *t = st->tab;
1742: int i;
1743: *p = st->tableid;
1744: p += 3;
1745: p = gentvdatetime(p, tv);
1746: p = gendescr(st, p, &t, 0xF0);
1747: i = p-b+1;
1748: b[1] = 0xF0 | (i >> 8);
1749: b[2] = i;
1750: crc32_calc(b, i-1, p);
1751: return p-b+4;
1752: }
1753:
1754: const static signed char syntax_sit[] = {
1755: SYNTAX_DESCR,
1756: SYNTAX_LOOP,
1757: SYNTAX_NUMBER(service_id)
1758: SYNTAX_NUMBER(running_status),
1759: SYNTAX_DESCR,
1760: SYNTAX_END
1761: };
1762:
1763: static int gentab_sit(struct sitab *st, unsigned char *b)
1764: {
1765: unsigned char *p = b;
1766: unsigned long *t = st->tab;
1.3 oskar 1767: unsigned char c;
1768: int i;
1.1 oskar 1769: *p = st->tableid;
1.3 oskar 1770: p += 3;
1771: *p++ = 0xFF;
1772: *p++ = 0xFF;
1773: *p++ = 0xC0 | (st->version << 1) | 0x01;
1774: *p++ = 0;
1775: *p++ = 0;
1776: p = gendescr(st, p, &t, 0xF0);
1777: i = *t++;
1778: while (i > 0) {
1779: *p++ = *t >> 8;
1780: *p++ = *t++;
1781: c = *t++ << 4;
1782: p = gendescr(st, p, &t, 0x80 | c);
1783: i -= 1;
1784: }
1785: i = p-b+1;
1786: b[1] = 0xF0 | (i >> 8);
1787: b[2] = i;
1788: crc32_calc(b, i-1, p);
1789: return p-b+4;
1.1 oskar 1790: }
1791:
1792: const static signed char syntax_dit[] = {
1793: SYNTAX_NUMBER(transition_flag),
1794: SYNTAX_END
1795: };
1796:
1797: static int gentab_dit(struct sitab *st, unsigned char *b)
1798: {
1799: unsigned char *p = b;
1800: unsigned long *t = st->tab;
1.3 oskar 1801: *p++ = st->tableid;
1802: *p++ = 0xF0;
1803: *p++ = 0x01;
1804: *p++ = (*t++ << 7) | 0x7F;
1.1 oskar 1805: return p-b;
1806: }
1807:
1808: const static signed char *const tab_syntax[num_si] = {
1809: &syntax_nit[0],
1810: &syntax_sdt[0],
1811: &syntax_bat[0],
1812: &syntax_eit[0],
1813: &syntax_rst[0],
1814: &syntax_tdt[0],
1815: &syntax_tot[0],
1816: &syntax_sit[0],
1817: &syntax_dit[0]
1818: };
1819:
1820: const static signed char *const *const syntax[2] = {
1821: &tab_syntax[0],
1822: &descr_syntax[0]
1823: };
1824:
1825: static void gentab(struct sitab *st, struct timeval *tv)
1826: {
1827: int l;
1828: unsigned char *b;
1829: memset(&descrcnt[0], 0, sizeof(descrcnt));
1830: l = st->pid - TABLE_PID_FIRST;
1831: b = &tabbuf[l][tabin[l]];
1832: *b++ = st->pid >> 8;
1833: *b++ = st->pid;
1834: switch (st->esi) {
1835: case nit: l = gentab_nit(st, b); break;
1836: case sdt: l = gentab_sdt(st, b); break;
1837: case bat: l = gentab_bat(st, b); break;
1838: case eit: l = gentab_eit(st, b); break;
1839: case rst: l = gentab_rst(st, b); break;
1840: case tdt: l = gentab_tdt(st, b, tv); break;
1841: case tot: l = gentab_tot(st, b, tv); break;
1842: case sit: l = gentab_sit(st, b); break;
1843: case dit: l = gentab_dit(st, b); break;
1844: default:
1845: fprintf(stderr, "internal error (gentab, %d)\n", st->esi);
1846: exit(1);
1847: }
1848: tabin[st->pid - TABLE_PID_FIRST] += l+2;
1849: }
1850:
1851: static enum enumsi alloctab(long pid, long tid)
1852: {
1853: enum enumsi e = si_none;
1854: switch (pid) {
1855: case 0x0010:
1856: if ((tid == 0x40) || (tid == 0x41)) {
1857: e = nit;
1858: } else {
1859: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1860: }
1861: break;
1862: case 0x0011:
1863: if ((tid == 0x42) || (tid == 0x46)) {
1864: e = sdt;
1865: } else if (tid == 0x4A) {
1866: e = bat;
1867: } else {
1868: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1869: }
1870: break;
1871: case 0x0012:
1872: if ((tid >= 0x4E) && (tid <= 0x6F)) {
1873: e = eit;
1874: } else {
1875: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1876: }
1877: break;
1878: case 0x0013:
1879: if (tid == 0x71) {
1880: e = rst;
1881: } else {
1882: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1883: }
1884: break;
1885: case 0x0014:
1886: if (tid == 0x70) {
1887: e = tdt;
1888: } else if (tid == 0x73) {
1889: e = tot;
1890: } else {
1891: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1892: }
1893: break;
1894: case 0x001E:
1895: if (tid == 0x7E) {
1896: e = dit;
1897: } else {
1898: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1899: }
1900: break;
1901: case 0x001F:
1902: if (tid == 0x7F) {
1903: e = sit;
1904: } else {
1905: fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
1906: }
1907: break;
1908: default:
1909: fprintf(stderr, "bad pid: 0x%04lx\n", pid);
1910: break;
1911: }
1912: return e;
1913: }
1914:
1915: static struct sitab **findtab(struct sitab **pst, long pid, long tableid)
1916: {
1917: struct sitab *st = *pst;
1918: while (st != NULL) {
1919: if ((st->pid == pid) && (st->tableid == tableid)) {
1920: return pst;
1921: }
1922: pst = &st->next;
1923: st = *pst;
1924: }
1925: return NULL;
1926: }
1927:
1928: static void droptab(long pid, long tableid)
1929: {
1930: struct sitab **pst;
1931: struct sitab *st;
1932: pst = &newtab;
1933: while ((pst = findtab(pst, pid, tableid)) != NULL) {
1934: st = *pst;
1935: *pst = st->next;
1936: close(st->u.a.fd);
1937: free(st->tab);
1938: free(st);
1939: }
1940: pst = &runtab;
1941: while ((pst = findtab(pst, pid, tableid)) != NULL) {
1942: st = *pst;
1943: *pst = st->next;
1944: nextversion[st->tableid - TABLEID_FIRST] = (st->version + 1) & 0x1F;
1945: free(st->tab);
1946: free(st);
1947: }
1948: }
1949:
1950: static void maketab(char typ, long pid, long tableid, long freqmsec, int fd)
1951: {
1952: struct sitab **pt;
1953: struct sitab *t;
1954: enum enumsi e;
1955: e = alloctab(pid, tableid);
1956: if (e >= 0) {
1957: pt = findtab(&newtab, pid, tableid);
1958: if (pt == NULL) {
1959: pt = findtab(&runtab, pid, tableid);
1960: } else {
1961: t = *pt;
1.2 oskar 1962: #ifdef DEBUG
1963: fprintf(stderr, "close old fd: %d\n", t->u.a.fd);
1964: #endif
1.1 oskar 1965: close(t->u.a.fd);
1966: }
1967: if (pt == NULL) {
1968: t = malloc(sizeof(struct sitab));
1969: t->pid = pid;
1970: t->tableid = tableid;
1971: t->version = nextversion[tableid - TABLEID_FIRST];
1972: } else {
1973: t = *pt;
1974: *pt = t->next;
1975: free(t->tab);
1976: t->version = (t->version + 1) & 0x1F;
1977: }
1978: t->typ = typ;
1979: t->freqmsec = freqmsec;
1980: t->esi = e;
1981: t->tab = NULL;
1982: memset(&t->descrnum[0], 0, sizeof(t->descrnum[0]));
1.2 oskar 1983: memset(&t->u, 0, sizeof(t->u));
1.1 oskar 1984: t->u.a.fd = fd;
1985: t->next = newtab;
1986: newtab = t;
1987: }
1988: }
1989:
1990: static int tabline(char *b, int n)
1991: {
1992: char *e, *a, *z;
1993: int i;
1994: long v[3];
1995: char c;
1996: if ((n <= 0) || ((e = memchr(b, '\n', n)) == NULL)) {
1997: return 0;
1998: }
1999: *e = 0;
2000: if (b >= e) {
2001: fprintf(stderr, "incomplete line: %s\n", b);
2002: } else {
2003: z = b+1;
2004: i = 0;
2005: c = toupper(*b);
2006: switch (c) {
2007: case '-':
2008: do {
2009: a = z;
2010: v[i] = strtol(a, &z, 0);
2011: } while ((a != z) && (++i < 2));
2012: if (a == z) {
2013: fprintf(stderr, "invalid line(%d): %s\n", a-b, b);
2014: } else {
2015: droptab(v[0], v[1]);
2016: }
2017: break;
2018: case 'S':
2019: do {
2020: a = z;
2021: v[i] = strtol(a, &z, 0);
2022: } while ((a != z) && (++i < 3));
2023: if (a == z) {
2024: fprintf(stderr, "invalid line(%d): %s\n", a-b, b);
2025: } else {
2026: while (isspace(*z)) {
2027: z += 1;
2028: }
2029: i = open(z, O_RDONLY | O_NONBLOCK);
2030: if (i < 0) {
2031: fprintf(stderr, "open failed(%d): %s\n", errno, z);
2032: } else {
2033: #ifdef DEBUG
2034: fprintf(stderr, "table: %c, %ld, %ld, %ld, <%s>\n",
2035: c, v[0], v[1], v[2], z);
2036: #endif
2037: maketab(c, v[0], v[1], v[2], i);
2038: }
2039: }
2040: break;
2041: }
2042: }
2043: return e-b+1;
2044: }
2045:
2046: static int taballoc(struct sitab *st, int cnt)
2047: {
2048: while (st->u.a.tablen < (st->u.a.itab + cnt)) {
2049: st->u.a.tablen += REALLOC_CHUNK;
2050: st->tab = realloc(st->tab, st->u.a.tablen * sizeof(unsigned long));
2051: if (st->tab == NULL) {
2052: return -ENOMEM;
2053: }
2054: }
2055: return 0;
2056: }
2057:
2058: static long longval(char **n, int d)
2059: {
2060: long v;
2061: int i;
2062: char c;
2063: v = 0;
2064: for (i = 0; i < d; i++) {
2065: c = *(*n)++;
2066: if (!isdigit(c)) {
2067: return -ENOMEM;
2068: }
2069: v = 10*v+c-'0';
2070: }
2071: return v;
2072: }
2073:
2074: static int siline(struct sitab *st, char *b, int n)
2075: {
2076: char *e, *a, *z;
2077: long v;
2078: int s, i;
2079: s = syntax[(st->u.a.isdescr > 0) ? 1 : 0]
2080: [(st->u.a.isdescr > 0) ? st->u.a.descrtag : st->esi][st->u.a.isyn];
2081: if ((s == SYNTAX_END) || (s == SYNTAX_LOOPEND)) {
2082: int lc;
2083: #ifdef DEBUG
2084: fprintf(stderr, "end:\n");
2085: #endif
2086: if ((lc = --st->u.a.loopcount[0]) <= 0) {
2087: if (lc == 0) {
2088: for (i = 0; i < LOOP_DEPTH-1; i++) {
2089: st->u.a.loopbegin[i] = st->u.a.loopbegin[i+1];
2090: st->u.a.loopcount[i] = st->u.a.loopcount[i+1];
2091: }
2092: st->u.a.loopcount[LOOP_DEPTH-1] = 0;
2093: if (s == SYNTAX_LOOPEND) {
2094: st->u.a.isyn += 1;
2095: } else if (st->u.a.isdescr > 0) {
2096: if (--st->u.a.isdescr == 0) {
2097: st->u.a.isyn = st->u.a.isyntab;
2098: }
2099: }
2100: return 0;
2101: } else {
2102: st->u.a.tablen = st->u.a.itab;
2103: st->tab = realloc(st->tab, st->u.a.itab * sizeof(unsigned long));
2104: return -ENOBUFS;
2105: }
2106: } else {
2107: st->u.a.isyn = st->u.a.loopbegin[0];
2108: return 0;
2109: }
2110: }
2111: if ((n <= 0) || ((e = memchr(b, '\n', n)) == NULL)) {
2112: return -EAGAIN;
2113: }
2114: *e = 0;
2115: a = b;
2116: while (isspace(*a)) {
2117: a += 1;
2118: }
2119: if (taballoc(st, 1)) {
2120: return -ENOMEM;
2121: }
2122: if (a != e) {
2123: switch (s) {
2124: default:
2125: if (s > 0) {
2126: fprintf(stderr, "internal syntax error\n");
2127: exit(1);
2128: }
2129: if (st->u.a.numcount == 0) {
2130: st->u.a.numcount = s;
2131: }
2132: v = strtoul(a, &z, 0);
2133: if (a == z) {
2134: return -EINVAL;
2135: }
2136: #ifdef DEBUG
2137: fprintf(stderr, "number: %ld, %d..%d\n", v, a-b, z-b);
2138: #endif
2139: st->tab[st->u.a.itab++] = v;
2140: if (++st->u.a.numcount == 0) {
2141: st->u.a.isyn += 1;
2142: }
2143: *e = '\n';
2144: return z-b;
2145: case SYNTAX_LOOP:
2146: v = strtol(a, &z, 0);
2147: if (a == z) {
2148: return -EINVAL;
2149: }
2150: #ifdef DEBUG
2151: fprintf(stderr, "loop: %ld, %d..%d\n", v, a-b, z-b);
2152: #endif
2153: st->tab[st->u.a.itab++] = v;
2154: if (v != 0) {
2155: if (st->u.a.isdescr > 0) {
2156: st->u.a.isdescr += 1;
2157: }
2158: for (i = LOOP_DEPTH-1; i >= 0; i--) {
2159: st->u.a.loopbegin[i+1] = st->u.a.loopbegin[i];
2160: st->u.a.loopcount[i+1] = st->u.a.loopcount[i];
2161: }
2162: st->u.a.loopbegin[0] = ++st->u.a.isyn;
2163: st->u.a.loopcount[0] = v;
2164: } else {
2165: do {
2166: st->u.a.isyn += 1;
2167: s = syntax[(st->u.a.isdescr > 0) ? 1 : 0]
2168: [(st->u.a.isdescr > 0) ? st->u.a.descrtag : st->esi]
2169: [st->u.a.isyn];
2170: if (s == SYNTAX_LOOP) {
2171: v += 1;
2172: }
2173: } while ((s != SYNTAX_END) && ((s != SYNTAX_LOOPEND) || (--v >= 0)));
2174: if (s == SYNTAX_LOOPEND) {
2175: st->u.a.isyn += 1;
2176: }
2177: }
2178: *e = '\n';
2179: return z-b;
2180: case SYNTAX_DESCR:
2181: v = strtol(a, &z, 0);
2182: if (a == z) {
2183: return -EINVAL;
2184: }
2185: #ifdef DEBUG
2186: fprintf(stderr, "descr: %ld, %d..%d\n", v, a-b, z-b);
2187: #endif
2188: st->tab[st->u.a.itab++] = v;
2189: st->u.a.isyn += 1;
2190: if (v != 0) {
2191: st->u.a.isdescr = 1;
2192: st->u.a.descrtag = 0;
2193: for (i = LOOP_DEPTH-1; i >= 0; i--) {
2194: st->u.a.loopbegin[i+1] = st->u.a.loopbegin[i];
2195: st->u.a.loopcount[i+1] = st->u.a.loopcount[i];
2196: }
2197: st->u.a.loopbegin[0] = 0;
2198: st->u.a.loopcount[0] = v;
2199: st->u.a.isyntab = st->u.a.isyn;
2200: st->u.a.isyn = 0;
2201: }
2202: *e = '\n';
2203: return z-b;
2204: case SYNTAX_DESCRTAG:
2205: v = strtol(a, &z, 0);
2206: if (a == z) {
2207: return -EINVAL;
2208: }
2209: #ifdef DEBUG
2210: fprintf(stderr, "descrtag: %ld, %d..%d\n", v, a-b, z-b);
2211: #endif
2212: st->tab[st->u.a.itab++] = v;
2213: v -= DESCR_FIRST;
2214: if ((v < 0) || (v > (DESCR_LAST - DESCR_FIRST))) {
2215: return -EINVAL;
2216: }
2217: st->descrnum[v] += 1;
2218: if (!((1 << st->esi) & possible_descr[v])) {
2219: return -EINVAL;
2220: }
2221: st->u.a.descrtag = v;
2222: st->u.a.isyn += 1;
2223: *e = '\n';
2224: return z-b;
2225: case SYNTAX_DATETIME:
2226: /* yyyy/mm/dd hh:mm:ss */
2227: z = a;
2228: i = e-z;
2229: if (i < 19) {
2230: return -EINVAL;
2231: }
2232: if (taballoc(st, 2)) {
2233: return -ENOMEM;
2234: }
2235: if ((v = longval(&z, 4)) < 0) {
2236: return v;
2237: }
2238: if ((v < 1582) || (*z++ != '/')) {
2239: return -EINVAL;
2240: }
2241: if ((s = longval(&z, 2)) < 0) {
2242: return s;
2243: }
2244: s -= 1;
2245: if ((s < 0) || (s > 11) || (*z++ != '/')) {
2246: return -EINVAL;
2247: }
2248: s -= 2;
2249: if (s < 0) {
2250: s += 12;
2251: v -= 1;
2252: }
2253: v = (1461*v)/4 - ((v/100+1)*3)/4 + (153*s)/5;
2254: if ((s = longval(&z, 2)) < 0) {
2255: return s;
2256: }
2257: if ((s <= 0) || (s > 31)) {
2258: return -EINVAL;
2259: }
2260: v += s - 678912;
2261: st->tab[st->u.a.itab++] = v;
2262: v = 0;
2263: s = ' ';
2264: for (i = 2; i >= 0; i--) {
2265: if (*z++ != s) {
2266: return -EINVAL;
2267: }
2268: s = *z++;
2269: if (!isdigit(s)) {
2270: return -EINVAL;
2271: }
2272: v = (v<<4) + (s-'0');
2273: s = *z++;
2274: if (!isdigit(s)) {
2275: return -EINVAL;
2276: }
2277: v = (v<<4) + (s-'0');
2278: s = ':';
2279: }
2280: st->tab[st->u.a.itab++] = v;
2281: #ifdef DEBUG
2282: fprintf(stderr, "datetime: %04lx %06lx, %d..%d\n",
2283: st->tab[st->u.a.itab-2], v, a-b, z-b);
2284: #endif
2285: st->u.a.isyn += 1;
2286: *e = '\n';
2287: return z-b;
2288: case SYNTAX_STRING:
2289: if (*a++ != '"') {
2290: return -EINVAL;
2291: }
2292: v = 0;
2293: z = strchr(a, '"');
2294: if (z == NULL) {
2295: return -EINVAL;
2296: }
2297: i = v;
2298: v += z-a;
2299: taballoc(st, 1 + (v + sizeof(long) - 1) / sizeof(long));
2300: memcpy(((char *)&st->tab[st->u.a.itab+1]) + i, a, z-a);
2301: z += 1;
2302: while (*z == '"') {
2303: a = z;
2304: z = strchr(a+1, '"');
2305: if (z == NULL) {
2306: return -EINVAL;
2307: }
2308: i = v;
2309: v += z-a;
2310: taballoc(st, 1 + (v + sizeof(long) - 1) / sizeof(long));
2311: memcpy(((char *)&st->tab[st->u.a.itab+1]) + i, a, z-a);
2312: z += 1;
2313: }
2314: st->tab[st->u.a.itab] = v;
2315: #ifdef DEBUG
2316: fprintf(stderr, "string: %ld, %d..%d\n", v, a-b, z-b);
2317: #endif
2318: st->u.a.itab += 1 + (v + sizeof(long) - 1) / sizeof(long);
2319: st->u.a.isyn += 1;
2320: *e = '\n';
2321: return z-b;
2322: }
2323: } else {
2324: return e-b+1;
2325: }
2326: }
2327:
2328: static unsigned int tab2ts(unsigned char *t, unsigned char *conticnt)
2329: {
2330: unsigned int l, d;
2331: unsigned char *i = &t[2];
2332: unsigned char *o;
2333: unsigned char c = *conticnt;
1.4 ! oskar 2334: l = ((t[3] & 0x0F) << 8) + t[4] + TS_HEADSLEN + TS_PFIELDLEN;
1.1 oskar 2335: d = (l-1) % (TS_PACKET_SIZE - TS_PACKET_HEADSIZE) + 1;
2336: if (outin >= OUTBUF_SIZE) {
2337: outin = 0;
2338: }
2339: o = &outbuf[outin];
2340: if (d <= (TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 1)) {
2341: if (d < (TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 1)) {
2342: o[5] = 0; /* no indicators, no flags, padding: */
2343: memset(&o[6], -1, TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 2 - d);
2344: }
2345: o[4] = TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 1 - d;
2346: o[3] = (0x00 << 6) | (0x03 << 4) | c;
2347: } else {
2348: o[3] = (0x00 << 6) | (0x01 << 4) | c;
2349: }
1.4 ! oskar 2350: o[TS_PACKET_SIZE - d] = 0; /* pointer_field */
! 2351: d -= TS_PFIELDLEN;
1.1 oskar 2352: memcpy(&o[TS_PACKET_SIZE - d], i, d);
2353: i += d;
1.4 ! oskar 2354: d = l - d - TS_PFIELDLEN;
1.1 oskar 2355: o[1] = (0 << 7) | (1 << 6) | (0 << 5) | t[0];
2356: o[2] = t[1];
2357: o[0] = TS_SYNC_BYTE;
2358: c = (c + 1) & 0x0F;
2359: outin += TS_PACKET_SIZE;
2360: while (d > 0) {
2361: if (outin >= OUTBUF_SIZE) {
2362: outin = 0;
2363: }
2364: o = &outbuf[outin];
2365: o[3] = (0x00 << 6) | (0x01 << 4) | c;
2366: memcpy(&o[4], i, TS_PACKET_SIZE-TS_PACKET_HEADSIZE);
2367: i += (TS_PACKET_SIZE - TS_PACKET_HEADSIZE);
2368: d -= (TS_PACKET_SIZE - TS_PACKET_HEADSIZE);
2369: o[1] = (0 << 7) | (0 << 6) | (0 << 5) | t[0];
2370: o[2] = t[1];
2371: o[0] = TS_SYNC_BYTE;
2372: c = (c + 1) & 0x0F;
2373: outin += TS_PACKET_SIZE;
2374: }
2375: *conticnt = c;
2376: return l+2;
2377: }
2378:
2379: static void argloop(int f0)
2380: {
2381: int i0 = 0;
2382: char buf0[PATH_MAX];
2383: do {
2384: int i, n, r, n0, n1, nst, tmo;
2385: struct timeval tv;
2386: struct sitab *st;
2387: struct sitab **pst;
2388: pollfd_init();
2389: if (f0 >= 0) {
2390: n0 = pollfd_add(f0, POLLIN);
2391: } else {
2392: n0 = -1;
2393: }
2394: if (newtab != NULL) {
2395: st = newtab;
2396: nst = pollfd_add(st->u.a.fd, POLLIN);
2397: while ((st = st->next) != NULL) {
2398: pollfd_add(st->u.a.fd, POLLIN);
2399: }
2400: } else {
2401: nst = -1;
2402: }
2403: tmo = -1;
2404: if (outin == 0) {
2405: r = OUTBUF_SIZE;
2406: n1 = -1;
2407: } else {
2408: r = outout - outin;
2409: if (r < 0) {
2410: r += OUTBUF_SIZE;
2411: }
2412: n1 = pollfd_add(STDOUT_FILENO, POLLOUT);
2413: }
2414: for (i = 0; i <= TABLE_PID_LAST-TABLE_PID_FIRST; i++) {
2415: if ((tabin[i] > tabout[i])
2416: && (r >= (((((tabbuf[i][tabout[i]+3] & 0x0F) << 8)
1.4 ! oskar 2417: + tabbuf[i][tabout[i]+4] + TS_HEADSLEN + TS_PFIELDLEN
1.1 oskar 2418: + TS_PACKET_SIZE - TS_PACKET_HEADSIZE)
2419: * 131) / 128))) {
2420: tmo = 0;
2421: break;
2422: }
2423: }
2424: gettimeofday(&tv, NULL);
2425: st = runtab;
2426: while (st != NULL) {
2427: i = st->pid - TABLE_PID_FIRST;
2428: if ((i < 0) || (i >= (TABLE_PID_LAST-TABLE_PID_FIRST))) {
2429: fprintf(stderr, "internal error (pid)\n");
2430: exit(1);
2431: }
2432: tabinold[i] = tabin[i];
2433: if (tmo != 0) {
2434: if (tabin[i] == 0) {
2435: i = (st->u.s.next.tv_sec - tv.tv_sec) * 1000
2436: + (st->u.s.next.tv_usec - tv.tv_usec) / 1000;
2437: if (i <= 0) {
2438: tmo = 0;
2439: } else if ((tmo < 0) || (i < tmo)) {
2440: tmo = i;
2441: }
2442: }
2443: }
2444: st = st->next;
2445: }
2446: n = pollfd_poll(tmo);
2447: gettimeofday(&tv, NULL);
2448: for (i = 0; i <= TABLE_PID_LAST-TABLE_PID_FIRST; i++) {
2449: while ((tabin[i] > tabout[i])
2450: && (r >= (((((tabbuf[i][tabout[i]+3] & 0x0F) << 8)
1.4 ! oskar 2451: + tabbuf[i][tabout[i]+4] + TS_HEADSLEN + TS_PFIELDLEN
1.1 oskar 2452: + TS_PACKET_SIZE - TS_PACKET_HEADSIZE)
2453: * 131) / 128))) {
2454: tabout[i] += tab2ts(&tabbuf[i][tabout[i]], &conticnt[i]);
2455: r = outout - outin;
2456: if (r < 0) {
2457: r += OUTBUF_SIZE;
2458: }
2459: }
2460: if (tabin[i] <= tabout[i]) {
2461: tabin[i] = tabout[i] = 0;
2462: }
2463: }
2464: if ((n > 0) && (n1 >= 0) && (r = pollfd_rev(n1))) {
2465: if (r & (POLLNVAL | POLLERR)) {
2466: fprintf(stderr, "poll error: %x\n", r);
2467: return;
2468: }
2469: if (outout >= OUTBUF_SIZE) {
2470: outout = 0;
2471: }
2472: r = ((outin > outout) ? outin : OUTBUF_SIZE) - outout;
2473: r = write(STDOUT_FILENO, &outbuf[outout], r);
2474: if (r < 0) {
2475: fprintf(stderr, "write error(%d)\n", errno);
2476: return;
2477: }
2478: if (r == 0) {
2479: exit(0);
2480: }
2481: outout += r;
2482: if (outout == outin) {
2483: outin = outout = 0;
2484: }
2485: }
2486: pst = &runtab;
2487: while ((st = *pst) != NULL) {
2488: i = st->pid - TABLE_PID_FIRST;
2489: if ((tabinold[i] == 0)
2490: && (tabin[i] < (TABBUF_SIZE-MAX_PSI_SIZE+1-2))
2491: && ((st->u.s.next.tv_sec < tv.tv_sec)
2492: || ((st->u.s.next.tv_sec == tv.tv_sec)
2493: && (st->u.s.next.tv_usec <= tv.tv_usec)))) {
2494: if (st->freqmsec > 0) {
2495: i = (st->u.s.next.tv_sec - tv.tv_sec) * 1000
2496: + (st->u.s.next.tv_usec - tv.tv_usec) / 1000;
2497: if (i < -st->freqmsec) {
2498: st->u.s.next = tv;
2499: } else {
2500: st->u.s.next.tv_sec += st->freqmsec / 1000;
2501: st->u.s.next.tv_usec += (st->freqmsec % 1000) * 1000;
2502: if (st->u.s.next.tv_usec > 1000000) {
2503: st->u.s.next.tv_usec -= 1000000;
2504: st->u.s.next.tv_sec += 1;
2505: }
2506: }
2507: }
2508: #ifdef DEBUG
2509: fprintf(stderr, "do tab: %ld.%06ld: %ld, %u\n", tv.tv_sec, tv.tv_usec,
2510: st->pid, st->tableid);
2511: #endif
2512: gentab(st, &tv);
2513: if (st->freqmsec <= 0) {
2514: *pst = st->next;
2515: nextversion[st->tableid - TABLEID_FIRST] = (st->version + 1) & 0x1F;
2516: free(st->tab);
2517: free(st);
2518: } else {
2519: pst = &st->next;
2520: }
2521: } else {
2522: pst = &st->next;
2523: }
2524: }
2525: if ((n > 0) && (nst >= 0)) {
2526: pst = &newtab;
2527: do {
2528: st = *pst;
2529: if ((r = pollfd_rev(nst))) {
2530: if (r & (POLLNVAL | POLLERR)) {
2531: fprintf(stderr, "poll error: %x\n", r);
2532: *pst = st->next;
2533: close(st->u.a.fd);
2534: free(st->tab);
2535: free(st);
2536: } else {
2537: i = st->u.a.ibuf;
2538: r = read(st->u.a.fd, &st->u.a.buf[i], sizeof(st->u.a.buf) - i - 1);
2539: if (r <= 0) {
2540: fprintf(stderr, "read error(%d): %d\n", errno, st->u.a.fd);
2541: *pst = st->next;
2542: close(st->u.a.fd);
2543: free(st->tab);
2544: free(st);
2545: } else {
2546: int j = 0;
2547: i += r;
2548: while ((r = siline(st, &st->u.a.buf[j], i)) >= 0) {
2549: j += r;
2550: i -= r;
2551: }
2552: switch (r) {
2553: case -ENOBUFS:
2554: *pst = st->next;
2555: close(st->u.a.fd);
2556: #ifdef DEBUG
2557: fprintf(stderr, "done, itab=%d\n", st->u.a.itab);
2558: for (i = 0; i < st->u.a.itab; i++) {
2559: fprintf(stderr, "%lu,", st->tab[i]);
2560: }
2561: fprintf(stderr, "\n");
2562: #endif
2563: i = st->pid - TABLE_PID_FIRST;
2564: if ((tabbuf[i] == NULL)
2565: && ((tabbuf[i] = malloc(TABBUF_SIZE)) == NULL)) {
2566: fprintf(stderr, "malloc failed for table buffer pid=%02lx\n",
2567: st->pid);
2568: free(st->tab);
2569: free(st);
2570: }
2571: st->next = runtab;
2572: runtab = st;
2573: st->u.s.next = tv;
2574: break;
2575: case -EAGAIN:
2576: if (i > 0) {
2577: memmove(&st->u.a.buf[0], &st->u.a.buf[j], i);
2578: }
2579: st->u.a.ibuf = i;
2580: pst = &st->next;
2581: break;
2582: default:
2583: fprintf(stderr, "eval error: %d\n", r);
2584: *pst = st->next;
2585: close(st->u.a.fd);
2586: free(st->tab);
2587: free(st);
2588: break;
2589: }
2590: }
2591: }
2592: n -= 1;
2593: } else {
2594: pst = &st->next;
2595: }
2596: nst += 1;
2597: } while ((*pst != NULL) && (n > 0));
2598: }
2599: if ((n > 0) && (n0 >= 0) && (r = pollfd_rev(n0))) {
2600: if (r & (POLLNVAL | POLLERR)) {
2601: fprintf(stderr, "poll error: %x\n", r);
2602: return;
2603: }
2604: r = read(f0, &buf0[i0], sizeof(buf0) - i0 - 1);
2605: if (r < 0) {
2606: fprintf(stderr, "read error(%d): %d\n", errno, f0);
2607: return;
2608: }
2609: if (r == 0) {
2610: return;
2611: }
2612: i0 += r;
2613: if (i0 == sizeof(buf0)-1) {
2614: buf0[sizeof(buf0)-1] = '\n';
2615: i0 += 1;
2616: }
2617: i = 0;
2618: while ((r = tabline(&buf0[i], i0))) {
2619: i += r;
2620: i0 -= r;
2621: }
2622: if (i0 > 0) {
2623: memmove(&buf0[0], &buf0[i], i0);
2624: }
2625: n -= 1;
2626: }
2627: } while (1);
2628: }
2629:
2630: int main(int argc, char *argv[])
2631: {
2632: int f = -1;
2633: int a;
2634: if (sizeof(unsigned) != sizeof(struct loop_descr *)) {
2635: fprintf(stderr, "data type prerequisites not met\n");
2636: return 1;
2637: }
2638: gen_crc32_table();
2639: system_init();
2640: unblockf(STDIN_FILENO);
2641: unblockf(STDOUT_FILENO);
2642: memset(&tabin[0], 0, sizeof(tabin));
2643: memset(&tabout[0], 0, sizeof(tabout));
2644: memset(&conticnt[0], 0, sizeof(conticnt));
2645: memset(&nextversion[0], 0, sizeof(nextversion));
2646: for (a = TABLE_PID_LAST-TABLE_PID_FIRST; a >= 0; a--) {
2647: tabbuf[a] = NULL;
2648: }
2649: a = 1;
2650: do {
2651: if ((a < argc) && (strcmp(argv[a], "-"))) {
2652: f = open(argv[a], O_RDONLY | O_NONBLOCK);
2653: if (f < 0) {
2654: fprintf(stderr, "open failed(%d): %s\n", errno, argv[a]);
2655: }
2656: } else {
2657: f = STDIN_FILENO;
2658: }
2659: argloop(f);
2660: } while (++a < argc);
2661: argloop(-1);
2662: return 0;
2663: }
LinuxTV legacy CVS <linuxtv.org/cvs>