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