aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authoretobi <git@e-tobi.net>2013-09-03 09:48:41 +0200
committeretobi <git@e-tobi.net>2013-09-03 09:48:41 +0200
commitab959d7b4194715870128e616b8e29d4a101e488 (patch)
tree61a746231d30817be73416a7d67763fd677a1042 /test
parent6b350466c4902c5b137e0efaf1d189128a7f18f5 (diff)
downloadlinux-dvb-apps-753ce5b9809deed38d6db404dc72e1e0e8ac4b29.tar.gz
Imported Upstream version 1.1.1+rev1207upstream/1.1.1+rev1207
Diffstat (limited to 'test')
-rw-r--r--test/Makefile64
-rw-r--r--test/README11
-rw-r--r--[-rwxr-xr-x]test/dia2
-rw-r--r--test/diseqc.c19
-rw-r--r--test/evtest.c251
-rw-r--r--test/hex_dump.c1
-rw-r--r--test/libdvbcfg/Makefile12
-rw-r--r--test/libdvbcfg/dvbcfg_test.c100
-rw-r--r--test/libdvbcfg/test_zapchannels.txt446
-rw-r--r--test/libdvben50221/Makefile14
-rw-r--r--test/libdvben50221/test-app.c854
-rw-r--r--test/libdvben50221/test-session.c171
-rw-r--r--test/libdvben50221/test-transport.c144
-rw-r--r--test/libdvbsec/Makefile12
-rw-r--r--test/libdvbsec/dvbsec_test.c85
-rw-r--r--test/libdvbsec/test_sec.txt28
-rw-r--r--test/libesg/Makefile12
-rw-r--r--test/libesg/samples/ESGProviderDiscoveryDescriptor.xml13
-rw-r--r--test/libesg/testesg.c563
-rw-r--r--test/libucsi/Makefile13
-rw-r--r--test/libucsi/testucsi.c3528
-rw-r--r--test/lnb.c101
-rw-r--r--test/lnb.h22
-rw-r--r--test/sendburst.c14
-rw-r--r--test/set22k.c18
-rw-r--r--test/setpid.c17
-rw-r--r--test/setvoltage.c18
-rw-r--r--test/szap2.c767
-rw-r--r--test/test.c81
-rw-r--r--test/test_audio.c41
-rw-r--r--test/test_av.c100
-rw-r--r--test/test_av_play.c526
-rw-r--r--test/test_dvr.c3
-rw-r--r--test/test_dvr_play.c1
-rw-r--r--test/test_front.c37
-rw-r--r--test/test_sec_ne.c7
-rw-r--r--test/test_sections.c3
-rw-r--r--test/test_stc.c1
-rw-r--r--test/test_stillimage.c7
-rw-r--r--test/test_switch.c106
-rw-r--r--test/test_tt.c1
-rw-r--r--test/test_vevent.c6
-rw-r--r--test/test_video.c51
-rw-r--r--test/video.c42
44 files changed, 7893 insertions, 420 deletions
diff --git a/test/Makefile b/test/Makefile
index ddff9ab..30cb9e3 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,37 +1,41 @@
-# Makefile for Linux DVB API Version 3 test programs
+# Makefile for linuxtv.org dvb-apps/test
-CC = gcc
-CFLAGS = -g -O2 -W -Wall -I../include
+objects = hex_dump.o lnb.o
-TARGETS = \
- diseqc \
- set22k \
- sendburst \
- setvoltage \
- setpid \
- video \
- test_sections \
- test_sec_ne \
- test_pes \
- test_dvr \
- test_dvr_play \
- test_tt \
- test_av \
- test_av_play \
- test_vevent \
- test_stc \
- test_stillimage
+binaries = diseqc \
+ sendburst \
+ set22k \
+ setpid \
+ setvoltage \
+ test_av \
+ test_av_play \
+ test_dvr \
+ test_dvr_play \
+ test_pes \
+ test_sec_ne \
+ test_sections \
+ test_stc \
+ test_stillimage \
+ test_tt \
+ test_vevent \
+ evtest \
+ video \
+ szap2
-# test \
-# test_audio \
-# test_front \
-# test_switch \
-# test_video \
+.PHONY: all
-all: $(TARGETS)
+all: $(binaries)
+ make -C libdvbcfg $@
+ make -C libdvben50221 $@
+ make -C libesg $@
+ make -C libucsi $@
-test_sections test_sec_ne test_pes test_tt: hex_dump.o
+$(binaries): $(objects)
-clean:
- rm -f $(TARGETS) *.o
+clean::
+ make -C libdvbcfg $@
+ make -C libdvben50221 $@
+ make -C libesg $@
+ make -C libucsi $@
+include ../Make.rules
diff --git a/test/README b/test/README
index b3f0cac..2b39936 100644
--- a/test/README
+++ b/test/README
@@ -1,4 +1,4 @@
-Various small test/sample programs for the Linux DVB API Version 2
+Various small test/sample programs for the Linux DVB API Version 2/3
The default devices used by the test programs are generally
/dev/dvb/adapter0/*0, and can be overridden using environment
@@ -33,13 +33,13 @@ test_vevent : Test VIDEO_GET_EVENT and poll() for video events
test_stc : Test DMX_GET_STC.
test_stillimage : Display single iframes as stillimages
- iframes can be created with the 'convert' tool from
- imagemagick and mpeg2encode from ftp.mpeg.org, and must
+ iframes can be created with the 'convert' tool from
+ imagemagick and mpeg2encode from ftp.mpeg.org, and must
have a supported size, e.g. 702x576
($ convert -sample 702x576\! test.jpg test.mpg)
-(test_av_play : Test playing MPEG TS from a file (apparently broken))
-
+test_av_play : Test playing MPEG PES (VDR format) from a file
+test_dvr_play : Test playing MPEG TS from a file (don't try, driver is broken)
test :
test_audio :
@@ -48,4 +48,3 @@ test_dvr :
test_front :
test_switch :
test_video :
-
diff --git a/test/dia b/test/dia
index 5cb2600..d737432 100755..100644
--- a/test/dia
+++ b/test/dia
@@ -4,4 +4,4 @@ for f in $@
do /usr/X11R6/bin/convert -geomtry 702x576 $f test.mpg
test_video test.mpg
rm test.mpg
-done \ No newline at end of file
+done
diff --git a/test/diseqc.c b/test/diseqc.c
index 8f2e411..5deb7fe 100644
--- a/test/diseqc.c
+++ b/test/diseqc.c
@@ -1,11 +1,13 @@
-/*
- * Test sending DiSEqC commands on a SAT frontend.
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX diseqc [test_seq_no]
- */
+#define USAGE \
+"\n" \
+"\nTest sending DiSEqC commands on a SAT frontend." \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX diseqc [test_seq_no|'all']" \
+"\n"
#include <pthread.h>
#include <time.h>
+#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
@@ -109,7 +111,10 @@ int main(int argc, char **argv)
return -1;
}
- if (argc > 1) {
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s [number|'all']\n" USAGE, argv[0]);
+ return 1;
+ } else if (strcmp(argv[1], "all")) {
int i = atol(argv[1]);
cmd[0] = &switch_cmds[i];
diseqc_send_msg(fd,
@@ -136,5 +141,3 @@ int main(int argc, char **argv)
return 0;
}
-
-
diff --git a/test/evtest.c b/test/evtest.c
new file mode 100644
index 0000000..a61593e
--- /dev/null
+++ b/test/evtest.c
@@ -0,0 +1,251 @@
+/*
+ * $Id: evtest.c,v 1.3 2005/08/15 20:43:52 js Exp $
+ *
+ * Copyright (c) 1999-2000 Vojtech Pavlik
+ *
+ * Event device test program
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+
+#include <linux/input.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *events[EV_MAX + 1] = { "Sync", "Key", "Relative", "Absolute", "Misc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, "LED", "Sound", NULL, "Repeat", "ForceFeedback", "Power", "ForceFeedbackStatus"};
+char *syncs[2] = { "Sync", "Config"};
+char *keys[KEY_MAX + 1] = {
+ // 0x000
+ "Reserved", "Esc", "1", "2", "3", "4", "5", "6",
+ "7", "8", "9", "0", "Minus", "Equal", "Backspace", "Tab",
+ // 0x010
+ "Q", "W", "E", "R", "T", "Y", "U", "I",
+ "O", "P", "LeftBrace", "RightBrace", "Enter", "LeftControl", "A", "S",
+ // 0x020
+ "D", "F", "G", "H", "J", "K", "L", "Semicolon",
+ "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z", "X", "C", "V",
+ // 0x030
+ "B", "N", "M", "Comma", "Dot", "Slash", "RightShift", "KPAsterisk",
+ "LeftAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5",
+ // 0x040
+ "F6", "F7", "F8", "F9", "F10", "NumLock", "ScrollLock", "KP7",
+ "KP8", "KP9", "KPMinus", "KP4", "KP5", "KP6", "KPPlus", "KP1",
+ // 0x050
+ "KP2", "KP3", "KP0", "KPDot", NULL, "ZENKAKUHANKAKU", "102nd", "F11",
+ "F12", "RO", "KATAKANA", "HIRAGANA", "HENKAN", "KATAKANAHIRAGANA", "MUHENKAN", "KPJPCOMMA",
+ // 0x060
+ "KPEnter", "RightCtrl", "KPSlash", "SysRq", "RightAlt", "LineFeed", "Home", "Up",
+ "PageUp", "Left", "Right", "End", "Down", "PageDown", "Insert", "Delete",
+ // 0x070
+ "Macro", "Mute", "VolumeDown", "VolumeUp", "Power", "KPEqual", "KPPlusMinus", "Pause",
+ NULL, "KPComma", "HANGUEL", "HANJA", "YEN", "LeftMeta", "RightMeta", "Compose",
+ // 0x080
+ "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open", "Paste",
+ "Find", "Cut", "Help", "Menu", "Calc", "Setup", "Sleep", "WakeUp",
+ // 0x090
+ "File", "SendFile", "DeleteFile", "X-fer", "Prog1", "Prog2", "WWW", "MSDOS",
+ "Coffee", "Direction", "CycleWindows", "Mail", "Bookmarks", "Computer", "Back", "Forward",
+ // 0x0A0
+ "CloseCD", "EjectCD", "EjectCloseCD", "NextSong", "PlayPause", "PreviousSong", "StopCD", "Record",
+ "Rewind", "Phone", "ISOKey", "Config", "HomePage", "Refresh", "Exit", "Move",
+ // 0x0B0
+ "Edit", "ScrollUp", "ScrollDown", "KPLeftParenthesis", "KPRightParenthesis", NULL, NULL, "F13",
+ "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21",
+ // 0x0C0
+ "F22", "F23", "F24", NULL, NULL, NULL, NULL, NULL,
+ "PlayCD", "PauseCD", "Prog3", "Prog4", NULL, "Suspend", "Close", "Play",
+ // 0x0D0
+ "FastForward", "BassBoost", "Print", "HP", "Camera", "Sound", "Question", "EMail",
+ "Chat", "Search", "Connect", "Finance", "Sport", "Shop", "AltErase", "Cancel",
+ // 0x0E0
+ "BrightnessDown", "BrightnessUp", "Media", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x0F0
+ "Unknown", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x100
+ "Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7",
+ "Btn8", "Btn9", NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x110
+ "LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn", "TaskBtn",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x120
+ "Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn", "BaseBtn", "BaseBtn2",
+ "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6", NULL, NULL, NULL, "BtnDead",
+ // 0x130
+ "BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR",
+ "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode", "BtnThumbL", "BtnThumbR", NULL,
+ // 0x140
+ "ToolPen", "ToolRubber", "ToolBrush", "ToolPencil", "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens",
+ NULL, NULL, "Touch", "Stylus", "Stylus2", "ToolDoubleTap", "ToolTripleTap", NULL,
+ // 0x150
+ "GearDown", "GearUp", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x160
+ "Ok", "Select", "Goto", "Clear", "Power2", "Option", "Info", "Time",
+ "Vendor", "Archive", "Program", "Channel", "Favorites", "EPG", "PVR", "MHP",
+ // 0x170
+ "Language", "Title", "Subtitle", "Angle", "Zoom", "Mode", "Keyboard", "Screen",
+ "PC", "TV", "TV2", "VCR", "VCR2", "Sat", "Sat2", "CD",
+ // 0x180
+ "Tape", "Radio", "Tuner", "Player", "Text", "DVD", "Aux", "MP3",
+ "Audio", "Video", "Directory", "List", "Memo", "Calendar", "Red", "Green",
+ // 0x190
+ "Yellow", "Blue", "ChannelUp", "ChannelDown", "First", "Last", "AB", "Next",
+ "Restart", "Slow", "Shuffle", "Break", "Previous", "Digits", "Teen", "Twen",
+ // 0x1A0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1B0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1C0
+ "DelEOL", "DelEOS", "InsLine", "DelLine", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1D0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1E0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x1F0
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };
+char *relatives[REL_MAX + 1] = {
+ "X", "Y", "Z", NULL, NULL, NULL, "HWheel", "Dial",
+ "Wheel", "Misc", NULL, NULL, NULL, NULL, NULL, NULL,
+};
+char *absolutes[ABS_MAX + 1] = {
+ // 0x00
+ "X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder",
+ "Wheel", "Gas", "Brake", NULL, NULL, NULL, NULL, NULL,
+ // 0x10
+ "Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat 3Y",
+ "Pressure", "Distance", "XTilt", "YTilt", "ToolWidth", NULL, NULL, NULL,
+ // 0x20
+ "Volume", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "Misc", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ // 0x30
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+char *leds[LED_MAX + 1] = { "NumLock", "CapsLock", "ScrollLock", "Compose", "Kana", "Sleep", "Suspend", "Mute" };
+char *repeats[REP_MAX + 1] = { "Delay", "Period" };
+char *sounds[SND_MAX + 1] = { "Bell", "Click" };
+
+char **names[EV_MAX + 1] = { syncs, keys, relatives, absolutes, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+NULL, NULL, leds, sounds, NULL, repeats, NULL, NULL, NULL };
+
+#ifndef BITS_PER_LONG
+#define BITS_PER_LONG (sizeof(long) * 8)
+#endif
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define BIT(x) (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+int main (int argc, char **argv)
+{
+ int fd, rd, i, j, k;
+ struct input_event ev[64];
+ int version;
+ unsigned short id[4];
+ unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+ char name[256] = "Unknown";
+ int _abs[5];
+
+ if (argc < 2) {
+ printf("Usage: evtest /dev/input/eventX\n");
+ printf("Where X = input device number\n");
+ exit(1);
+ }
+
+ if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
+ perror("evtest");
+ exit(1);
+ }
+
+ if (ioctl(fd, EVIOCGVERSION, &version)) {
+ perror("evtest: can't get version");
+ exit(1);
+ }
+
+ printf("Input driver version is %d.%d.%d\n",
+ version >> 16, (version >> 8) & 0xff, version & 0xff);
+
+ ioctl(fd, EVIOCGID, id);
+ printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
+ id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
+
+ ioctl(fd, EVIOCGNAME(sizeof(name)), name);
+ printf("Input device name: \"%s\"\n", name);
+
+ memset(bit, 0, sizeof(bit));
+ ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+ printf("Supported events:\n");
+
+ for (i = 0; i < EV_MAX; i++)
+ if (test_bit(i, bit[0])) {
+ printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
+ ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
+ for (j = 0; j < KEY_MAX; j++)
+ if (test_bit(j, bit[i])) {
+ printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
+ if (i == EV_ABS) {
+ ioctl(fd, EVIOCGABS(j), _abs);
+ for (k = 0; k < 5; k++)
+ if ((k < 3) || _abs[k])
+ printf(" %s %6d\n", absval[k], _abs[k]);
+ }
+ }
+ }
+
+
+ printf("Testing ... (interrupt to exit)\n");
+
+ while (1) {
+ rd = read(fd, ev, sizeof(struct input_event) * 64);
+
+ if (rd < (int) sizeof(struct input_event)) {
+ printf("yyy\n");
+ perror("\nevtest: error reading");
+ exit (1);
+ }
+
+ for (i = 0; i < rd / (int) sizeof(struct input_event); i++)
+ printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
+ ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
+ events[ev[i].type] ? events[ev[i].type] : "?",
+ ev[i].code,
+ names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
+ ev[i].value);
+
+ }
+}
diff --git a/test/hex_dump.c b/test/hex_dump.c
index c7c8ede..b5c08cb 100644
--- a/test/hex_dump.c
+++ b/test/hex_dump.c
@@ -60,4 +60,3 @@ void hex_dump(uint8_t data[], int bytes)
}
printf("\n");
}
-
diff --git a/test/libdvbcfg/Makefile b/test/libdvbcfg/Makefile
new file mode 100644
index 0000000..7705f9b
--- /dev/null
+++ b/test/libdvbcfg/Makefile
@@ -0,0 +1,12 @@
+# Makefile for linuxtv.org dvb-apps/test/libdvbcfg
+
+binaries = dvbcfg_test
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbcfg/libdvbcfg.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libdvbcfg/dvbcfg_test.c b/test/libdvbcfg/dvbcfg_test.c
new file mode 100644
index 0000000..de10e43
--- /dev/null
+++ b/test/libdvbcfg/dvbcfg_test.c
@@ -0,0 +1,100 @@
+/**
+ * dvbcfg testing.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+
+void syntax(void);
+
+struct dvbcfg_zapchannel *channels = NULL;
+int zapcount = 0;
+int zappos = 0;
+
+int zapload_callback(struct dvbcfg_zapchannel *channel, void *private);
+int zapsave_callback(struct dvbcfg_zapchannel *channel, void *private);
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4) {
+ syntax();
+ }
+
+ if (!strcmp(argv[1], "-zapchannel")) {
+
+ FILE *f = fopen(argv[2], "r");
+ if (!f) {
+ fprintf(stderr, "Unable to load %s\n", argv[2]);
+ exit(1);
+ }
+ dvbcfg_zapchannel_parse(f, zapload_callback, NULL);
+ fclose(f);
+
+ f = fopen(argv[3], "w");
+ if (!f) {
+ fprintf(stderr, "Unable to write %s\n", argv[3]);
+ exit(1);
+ }
+ dvbcfg_zapchannel_save(f, zapsave_callback, NULL);
+ fclose(f);
+
+ } else {
+ syntax();
+ }
+
+ exit(0);
+}
+
+int zapload_callback(struct dvbcfg_zapchannel *channel, void *private)
+{
+ (void) private;
+
+ struct dvbcfg_zapchannel *tmp = realloc(channels, (zapcount+1) * sizeof(struct dvbcfg_zapchannel));
+ if (tmp == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ channels = tmp;
+
+ memcpy(&channels[zapcount++], channel, sizeof(struct dvbcfg_zapchannel));
+
+ return 0;
+}
+
+int zapsave_callback(struct dvbcfg_zapchannel *channel, void *private)
+{
+ (void) private;
+
+ if (zappos >= zapcount)
+ return 1;
+
+ memcpy(channel, channels + zappos, sizeof(struct dvbcfg_zapchannel));
+ zappos++;
+
+ return 0;
+}
+
+void syntax()
+{
+ fprintf(stderr,
+ "Syntax: dvbcfg_test <-zapchannel> <input filename> <output filename>\n");
+ exit(1);
+}
diff --git a/test/libdvbcfg/test_zapchannels.txt b/test/libdvbcfg/test_zapchannels.txt
new file mode 100644
index 0000000..98a5b41
--- /dev/null
+++ b/test/libdvbcfg/test_zapchannels.txt
@@ -0,0 +1,446 @@
+# Most of the major channels in the Raleigh Durham Area. Frequencies the NTSC center freq.
+WRAL:707000000:8VSB:33:36
+WNCN:719000000:8VSB:49:52
+WTVD:701000000:8VSB:49:52
+WRAZ:683000000:8VSB:49:52
+WUNC:743000000:8VSB:49:52
+WRDU:551000000:8VSB:33:36
+WLFL:731000000:8VSB:33:36
+3sat:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:210:220
+ARD-Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1805
+CNBC:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:510:520
+DLF-Köln:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:810
+DLR-Berlin:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:710
+EinsExtra:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102
+EinsFestival:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202
+EinsMuXx:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:301:302
+EuroNews:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2221:2233
+Eurosport:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:410:420
+Fritz:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:901
+KiKa:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:310:320
+MDR FERNSEHEN:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:401:402
+MDR KULTUR:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:801
+MDR info:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1101
+MHP ARD Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:102
+NDR Fernsehen:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2401:2402
+ORB-Fernsehen:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:501:502
+RADIOmultikulti:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1301
+Radio 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:701
+SFB1:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602
+SWR2:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1401
+SÜDWEST BW:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:801:802
+SÜDWEST RP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3101:3102
+WDR 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1501
+WDR 5:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1601
+ZDF:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:110:120
+ZDFdigitext:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+ZDFdokukanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:660:670
+ZDFinfokanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:610:620
+ZDFtheaterkanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+JUMP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1001
+SPUTNIK:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1201
+Österreich 1:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:169
+ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632
+ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632
+Adagio:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+All Jazz:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Avante:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:741:743
+B5 aktuell:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3101
+BBC Prime:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:761:762
+BData3:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+BData4:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+BData5:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+BR-alpha:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702
+Barock Fantasie:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Bayerisches FS:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202
+Bayern 1:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3601
+Bayern 4 Klassik:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3001
+BibelTV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:731:732
+Bloomberg:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+CLASSICA:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:767:768
+COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:656
+Canal 24 Horas:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:991:992
+Club:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:711:713
+Cristal New Age:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+DANCE:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:304
+DW-tv:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:634:632
+Das Erste:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102
+Detskij Mir:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:931:932
+ERT-Sat:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:691:692
+Einstein TV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702
+Euronews:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:597:596
+Eurosport News:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:771:772
+Extreme Sports:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:791:793
+Extreme Sports:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Fashion TV:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Fox Kids:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:671:672
+Fox Kids:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:671:673
+GOLD:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:320
+HITLISTE:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:784
+HR XXL:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3501
+JAZZ:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:640
+Jazz legends:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Kabel Wizard:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Kanal 7:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Kanal 7:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:49:52
+Kanal D:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:651:652
+Kanal D:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:651:652
+LATIN:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:368
+Landscape:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Leitseite:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2254:0
+Liberty TV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:721:723
+MTV Base:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:781:782
+MV-Test:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Modem-Setup:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Movie Sounds:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Musica Antica:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Musica Camerata:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+NDR Info:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3701
+NTV international:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+NTVI:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:611:612
+Nashe Kino:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:621:622
+NordwestRadio:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3801
+OLD GOLD:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:336
+Opernfestival:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PCNE:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:681:682
+PREMIERE SPORT INTERACTIVE:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 1:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 2:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 3:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+PREMIERE DIREKT 4:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2815:2816
+PREMIERE EROTIK:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280
+PREMIERE NOSTALGIE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2559:2560
+PREMIERE SERIE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024
+PREMIERE SPORT 1:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:258
+PREMIERE SPORT 2:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3839:3840
+PREMIERE START:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256
+Parlamentsfernsehen:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:33:36
+Phoenix:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:901:902
+Portal:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+RTP Internacional:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:661:662
+Rai 1:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:951:952
+Rai 2:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:961:962
+Rai 3:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:971:972
+SCHLAGER:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384
+SR 1:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3901
+SR Fernsehen Suedwest:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:501:502
+Show TV:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:911:912
+Sinfonica:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+TGRT:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:921:922
+TM V1.0:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+TV Polonia:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:641:642
+TVEi:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:981:982
+TW1:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:751:752
+Test-R:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702
+Travel:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:595:594
+VCR-Setup:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+VH1 Classic:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:604:603
+Videotext:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+WDR FERNSEHEN:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602
+ZEE TV:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+arte:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:401:403
+hessen fernsehen:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:301:302
+hr-chronos:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3201
+hr-klassik:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3401
+hr2:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3301
+13 TH STREET:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2303:2304
+ALTERNATIVE ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:544
+BEATE-UHSE.TV:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024
+CHILLOUT:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:400
+CLASSIC ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:352
+DISCOVERY CHANNEL:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1792
+DISNEY CHANNEL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2559:2560
+DEUTSCHE HITS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:800
+EASY LISTENING:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:608
+Einstein:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+FILM & MUSICAL:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592
+FOX KIDS:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280
+GOLDSTAR TV:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3839:3840
+HARD ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:816
+HEIMATKANAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
+HIP HOP/R&B:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:576
+JUNIOR:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256
+K-TOON:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+KLASSIK POPULÄR:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:624
+KRIMI &CO:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
+LOVE SONGS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592
+NEW COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384
+ORCHESTRALE WERKE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:560
+PLANET:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1792
+PREMIERE 1:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:511:512
+PREMIERE 2:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1793
+PREMIERE 3:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2303:2304
+PREMIERE 4:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:767:768
+PREMIERE 5:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280
+PREMIERE 6:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536
+PREMIERE 7:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024
+SOUL CLASSICS:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:352
+STUDIO UNIVERSAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2047:2048
+Sonnenklar TV:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0
+Das Erste:11837:h:0:27500:101:102:28106
+ZDF:11954:h:0:27500:110:120:28006
+3sat:11954:h:0:27500:210:220:28007
+EinsMuXx:12110:h:0:27500:301:302:28203
+EinsFestival:12110:h:0:27500:201:202:28202
+EinsExtra:12110:h:0:27500:101:102:28201
+MDR FERNSEHEN:12110:h:0:27500:401:402:28204
+ORB-Fernsehen:12110:h:0:27500:501:502:28205
+B1 Berlin:12110:h:0:27500:601:602:28206
+SWR Fernsehen:11837:h:0:27500:801:802:28113
+SR Fernsehen Suedwes:11837:h:0:27500:501:502:28110
+hessen fernsehen:11837:h:0:27500:301:302:28108
+WDR FERNSEHEN:11837:h:0:27500:601:602:28111
+Bayerisches FS:11837:h:0:27500:201:202:28107
+N3:12110:h:0:27500:2401:2402:28224
+BR-alpha:11837:h:0:27500:701:702:28112
+KiKa:11954:h:0:27500:310:320:28008
+arte:11836:h:0:27500:401:402:28109
+ZDF Theaterkanal:11954:h:0:27500:1110:1120:28016
+ZDF.info:11954:h:0:27500:610:620:28011
+ZDF.doku:11954:h:0:27500:660:670:28014
+Phoenix:11837:h:0:27500:901:902:28114
+DW-tv:10786:v:0:21997:305:306:9005
+RTL Television:12188:h:0:27500:163:104:12003
+SAT.1:12480:v:0:27500:1791:1792:46
+ProSieben:12480:v:0:27500:255:256:898
+RTL2:12188:h:0:27500:166:128:12020
+Super RTL:12188:h:0:27500:165:120:12040
+KABEL1:12480:v:0:27500:511:512:899
+VOX:12188:h:0:27500:167:136:12060
+tm3:12480:v:0:27500:767:768:897
+Bloomberg TV Germany:12552:v:0:22000:162:99:12160
+EuroNews:11954:h:0:27500:2221:2233:28015
+N24:12480:v:0:27500:2047:2048:47
+n-tv:12670:v:0:22000:162:96:12730
+DSF:12480:v:0:27500:1023:1024:900
+Eurosport:11954:h:0:27500:410:420:28009
+Via 1 - Sch ner Re:12148:h:0:27500:511:512:44
+Home Order Tel:12480:v:0:27500:1279:1280:40
+QVC GERMANY:12552:v:0:22000:165:166:12100
+TW 1:12692:h:0:22000:166:167:13013
+Canal Canarias:12441:v:0:27500:513:681:29700
+ProSieben A:12051:v:0:27500:161:84:20002
+ProSieben CH:12051:v:0:27500:289:290:20001
+Kabel 1 Austria:12051:v:0:27500:166:167:20004
+Kabel 1 Schweiz:12051:v:0:27500:162:163:20003
+CNN Int.:12168:v:0:27500:165:100:28512
+Sky News:12552:v:0:22000:305:306:3995
+Travel:12168:v:0:27500:163:92:28001
+AB SAT / XXL:12266:h:0:27500:164:96:17004
+MOTEURS:12266:h:0:27500:160:80:17000
+HOT GM:12148:h:0:27500:767:768:45
+KTO:12129:v:0:27500:170:120:8411
+LA CINQUIEME:12207:v:0:27500:160:80:8501
+LCP:12207:v:0:27500:165:100:8506
+LibertyTV.com:12611:v:0:22000:941:942:12280
+TV5 Europe:12611:v:0:22000:45:46:12240
+Motors TV:12611:v:0:22000:191:194:12300
+Wishline:12611:v:0:22000:214:216:12320
+TV 5:10786:v:0:21997:164:112:9001
+RTM - MAROC:10786:v:0:21997:162:96:9002
+ESC1 - EGYPTE:10786:v:0:21997:163:104:9003
+RAI 1:10786:v:0:21997:289:290:9004
+RTPI:10786:v:0:21997:300:301:9006
+TV7:10786:v:0:21997:166:128:9007
+ARTE:10786:v:0:21997:167:136:9009
+Colourbars:12611:v:0:22000:48:49:3982
+Alice:12611:v:0:22000:162:96:12200
+Video Italia:12611:v:0:22000:121:122:12220
+ANDALUCIA TV:11934:v:0:27500:166:104:29011
+TVC INT.:12441:v:0:27500:512:660:29701
+TV4:11992:h:0:27500:165:98:20365
+TV Niepokalanow:11876:h:0:27500:161:82:20601
+VIVA:12670:v:0:22000:309:310:12732
+VIVA ZWEI:12552:v:0:22000:171:172:12120
+MTV Central:12699:v:0:22000:3031:3032:28643
+ONYX:12692:h:1:27500:161:84:502
+VIVA polska:11603:h:1:27500:190:191:611
+DeeJay TV:11603:h:1:27500:160:161:602
+NBC:11053:h:1:27500:550:551:8008
+EWTN:10722:h:1:29900:1001:1201:4601
+MTA INTL:10722:h:1:29900:1004:1204:4604
+VOX:11053:h:1:27500:500:501:8002
+SAT.1 A:11053:h:1:27500:511:512:8003
+RTL2 AUSTRIA:11053:h:1:27500:520:521:8004
+ZDF:11053:h:1:27500:570:571:8011
+K-TV:11053:h:1:27500:580:581:8012
+RTL Television:11053:h:1:27500:160:80:8001
+ARTE:11059:v:1:6510:98:99:1
+HOT Italia:11095:h:1:27500:4194:4195:3714
+Olisat:11095:h:1:27500:33:34:3718
+VIVA-POLSKA:11128:h:1:4340:98:99:1
+DW-tv:11195:v:1:9099:101:102:5301
+Canal 24 Horas:11203:h:1:3999:4130:4131:5301
+TV5:11337:v:1:5631:512:640:1
+SAT.1 CH:11603:h:1:27500:101:102:601
+KurdSat:11603:h:1:27500:111:112:603
+ARD "Das Erste":11603:h:1:27500:172:173:606
+RTL 2 CH:11603:h:1:27500:175:176:609
+Super RTL A:11603:h:1:27500:180:181:610
+TV ROMANIA:11622:v:1:27500:227:247:10707
+MRTV:11622:v:1:27500:222:242:10702
+102.5 HIT Ch:11622:v:1:27500:224:244:10704
+TLC SAT:11622:v:1:27500:225:245:10705
+PRO-SAT:11622:v:1:27500:246:226:10706
+Channel SUN:11622:v:1:27500:229:249:10709
+Racing Channel:11622:v:1:27500:228:248:10708
+3 ABN:11622:v:1:27500:221:241:10701
+Bloom.Germany:11642:h:1:27500:1460:1420:4
+Bloomberg TV UK:11642:h:1:27500:1560:1520:4
+Sat 7:11642:h:1:27500:1660:1620:4
+EDTV 1:11746:h:1:27500:4130:4131:9501
+EDTV SPORT:11746:h:1:27500:4386:4387:9502
+EDTV BUSINESS:11746:h:1:27500:4642:4643:9503
+EDTV DRAMA:11746:h:1:27500:4898:4899:9504
+RAI1:11765:v:1:27499:160:80:3401
+RAI2:11765:v:1:27499:161:84:3402
+RAI3:11765:v:1:27499:162:88:3403
+RaiWayTEST2:11765:v:1:27499:516:654:3405
+RAIMOSAICO:11765:v:1:27499:518:8191:3407
+RAINews24:11803:v:1:27500:516:654:3301
+CAMERA DEPUTATI:11803:v:1:27500:517:655:3302
+TELEPACE:11803:v:1:27500:515:653:3304
+RAISPORTSAT:11803:v:1:27500:512:650:3305
+RAINettunoSAT2:11803:v:1:27500:513:651:3306
+RAIeducational:11803:v:1:27500:514:652:3307
+RAINettunoSAT1:11803:v:1:27500:519:657:3308
+SAT2000:11803:v:1:27500:518:656:3309
+I1:11918:v:1:27499:512:650:1
+C5:11918:v:1:27499:513:660:2
+R4:11918:v:1:27499:514:670:3
+Telesierra:12091:h:1:27500:4160:4161:8704
+C. Milagro:12091:h:1:27500:4368:4369:8711
+Italia Sat:12091:h:1:27500:4600:4601:8728
+TVE Internacional:12091:h:1:27500:4208:4209:8707
+Fiesta:12091:h:1:27500:4432:4433:8720
+Retelsat:12091:h:1:27500:4464:4465:8722
+ART EUROPE:12013:h:1:27495:164:96:450
+EGYPT SAT. CH. 2:12013:h:1:27495:166:104:470
+IQRA:12013:h:1:27495:168:112:474
+MAURITANIA TV:12110:v:1:27500:230:231:704
+ARMENIA TV:12110:v:1:27500:240:241:705
+SAILING CHANNEL:12110:v:1:27500:260:261:707
+AL JAZEERA:12110:v:1:27500:270:271:708
+Coming Soon TV:12110:v:1:27500:310:311:717
+SaluteBenessere:12110:v:1:27500:320:321:718
+AH-EDP1:12148:v:1:27499:96:97:7201
+AH-EDP2:12148:v:1:27499:112:113:7202
+Espresso:12148:v:1:27499:192:193:7203
+Alice:12148:v:1:27499:160:161:7220
+Nuvolari:12148:v:1:27499:176:177:7221
+Leonardo:12148:v:1:27499:128:129:7222
+AH-EDP3:12148:v:1:27499:36:37:7205
+OTE Promo:12187:v:1:27500:517:655:1001
+RTS SAT:12187:v:1:27500:519:657:1022
+ERT SAT:12187:v:1:27500:514:652:1102
+EXTRA:12187:v:1:27500:516:654:1106
+TRIAL:12187:v:1:27500:513:651:1108
+Minimax:11303:h:1:19540:300:301:3
+TVN1:12209:h:1:5631:4194:4195:1
+RR TEST:10978:v:1:8998:33:34:1
+TV 5 Thailand:10978:v:1:8998:1057:1058:2
+TEST-1:10978:v:1:8998:3105:3106:4
+FASHION:12244:h:1:27500:123:133:103
+AJARA TV:12244:h:1:27500:127:137:107
+SLO-TV1:12300:v:1:27495:200:201:3201
+POLONIA 1:12302:v:1:27500:205:206:3203
+SUPER 1:12302:v:1:27500:207:208:3207
+NAPOLI INT.:12302:v:1:27500:240:241:3210
+MAGIC:12302:v:1:27500:245:246:3211
+COUNTDOWN:12302:v:1:27500:235:236:3212
+TBNE:12302:v:1:27500:230:231:3213
+NAPOLI CHANNEL:12302:v:1:27500:227:228:3215
+KURDISTAN TV:12302:v:1:27500:225:226:3214
+ATLAS TV:12379:v:1:27500:3022:3032:3002
+TELE 24 SWITZERLAND:12379:v:1:27500:3023:3033:3003
+Abu Dhabi TV:12379:v:1:27500:3024:3034:3004
+RTV MONTENEGRO:12379:v:1:27500:3026:3036:3006
+JAAM-E-JAM 1:12436:h:1:27500:160:80:1
+JAAM-E-JAM 2:12436:h:1:27500:161:82:2
+SAHAR:12436:h:1:27500:162:84:3
+SAHAR 2:12436:h:1:27500:163:86:4
+IRINN:12436:h:1:27500:164:88:5
+Musicmax:11303:h:1:19540:500:501:6
+TEST:12474:h:1:27500:771:8191:10608
+EbS:12474:h:1:27500:101:201:10601
+MOU.2:12474:h:1:27500:42:43:10602
+PINK PLUS:12474:h:1:27500:308:256:10605
+LibertyTV.com:12474:h:1:27500:941:942:10603
+2M Maroc:12474:h:1:27500:601:602:10607
+ZEE TV:12474:h:1:27500:910:911:10604
+WorldNet Europe:12483:v:1:8299:4260:4220:1
+WorldNet:12483:v:1:8299:4560:4520:4
+SICILIA INTERNATIONA:12519:v:1:27499:501:502:8309
+SARDEGNA UNO:12519:v:1:27499:503:504:8310
+EuroMed:12519:v:1:27499:510:511:8312
+TGRT:12519:v:1:27499:505:506:8313
+VIDEOLINA:12519:v:1:27499:515:516:8318
+MEDIOLANUM:12538:h:1:27500:1131:1132:8987
+www.travel:12538:h:1:27500:1180:1183:8992
+MonteCarloSat:12538:h:1:27500:5126:5122:8877
+Bulgaria TV:12538:h:1:27500:4612:4613:8827
+TVN1:12571:h:1:5631:4194:4195:1
+JSTV 1:12595:v:1:27500:2000:2001:8213
+JSTV 2:12595:v:1:27500:2011:2013:8214
+MBC:12595:v:1:27500:160:80:8201
+ANN:12595:v:1:27500:161:84:8202
+BET:12595:v:1:27500:167:108:8208
+EuroNews:12595:v:1:27500:2221:2231:8211
+Sharjah Arabs:12653:h:1:27500:1160:1120:1
+Qatar Arabs:12653:h:1:27500:1260:1220:2
+Saudi 1 Arabs:12653:h:1:27500:1360:1320:3
+Kuwait Arabs:12653:h:1:27500:1460:1420:4
+Libya Arabs:12653:h:1:27500:1560:1520:5
+Sudan Arabs:12653:h:1:27500:1660:1620:6
+Oman Arabs:12653:h:1:27500:1760:1720:7
+Jordan Arabs:12653:h:1:27500:1860:1820:8
+IRAQ TV:12653:h:1:27500:1960:1920:9
+Dubai Sport:12653:h:1:27500:1060:1020:10
+Digitaly:12672:v:1:27500:220:221:4203
+Telemarket:12672:v:1:27500:350:351:4211
+eVision:12672:v:1:27500:360:361:4214
+Thai TV5:12672:v:1:27500:200:201:4201
+Studio Europa:12672:v:1:27500:230:231:4204
+Video Italia:12672:v:1:27500:340:341:4210
+GAME NETWORK:12672:v:1:27500:291:292:4213
+BBC-Choice:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621
+BBC-Knowledge:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:630:631
+BBC-News24:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641
+BBC-1:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601
+BBC-Parliament:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660
+BBC-2:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611
+ITV-1:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:513:651
+ITV-2:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2818:2819
+ITV-Sport:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2836:2837
+FilmFour:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2822:2823
+C4:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2826:2827
+E4:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2831:2832
+C5:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018
+Shop:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050
+ITVSelect-Info:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6065:6066
+ITVSelect-1:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6081:6082
+ITVSelect-2:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6097:6098
+ITVSelect-3:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6113:6114
+ITVSelect-4:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6129:6130
+Carlton-Cinema:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289
+Sky-One:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545
+Sky-Sports-1:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801
+Sky-Premier:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1056:1057
+CartoonNetwork:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313
+UK-Horizons:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2336:2337
+ITV-Sport-Plus:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2592:2593
+ITVSportSelect:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:2596
+BreezeMen&Mtrs:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801
+Granada-Plus:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545
+MTV:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1568:1569
+Sky-Movie-Max:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313
+Sky-Sports-2:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2080:2081
+UK-Gold:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289
+Wellbeing:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1824:1825
+PLAY-uk:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289
+UK-Style:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545
+no-name:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801
+Discovery:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313
+Nick/Paramount:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2080:2081
+Sky-Sports-3:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2336:2337
+Brit-Eurosport:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2592:2593
diff --git a/test/libdvben50221/Makefile b/test/libdvben50221/Makefile
new file mode 100644
index 0000000..cd29679
--- /dev/null
+++ b/test/libdvben50221/Makefile
@@ -0,0 +1,14 @@
+# Makefile for linuxtv.org dvb-apps/test/libdvben50221
+
+binaries = test-app \
+ test-session \
+ test-transport
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbapi/libdvbapi.a ../../lib/libdvben50221/libdvben50221.a ../../lib/libucsi/libucsi.a -lpthread
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libdvben50221/test-app.c b/test/libdvben50221/test-app.c
new file mode 100644
index 0000000..d99ec01
--- /dev/null
+++ b/test/libdvben50221/test-app.c
@@ -0,0 +1,854 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <libdvben50221/en50221_session.h>
+#include <libdvben50221/en50221_app_utils.h>
+#include <libdvben50221/en50221_app_ai.h>
+#include <libdvben50221/en50221_app_auth.h>
+#include <libdvben50221/en50221_app_ca.h>
+#include <libdvben50221/en50221_app_datetime.h>
+#include <libdvben50221/en50221_app_dvb.h>
+#include <libdvben50221/en50221_app_epg.h>
+#include <libdvben50221/en50221_app_lowspeed.h>
+#include <libdvben50221/en50221_app_mmi.h>
+#include <libdvben50221/en50221_app_rm.h>
+#include <libdvben50221/en50221_app_smartcard.h>
+#include <libdvben50221/en50221_app_teletext.h>
+#include <libdvbapi/dvbca.h>
+#include <pthread.h>
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libucsi/section.h>
+#include <libucsi/mpeg/section.h>
+
+#define DEFAULT_SLOT 0
+
+#define MAX_SESSIONS 256
+#define MAX_TC 32
+
+void *stackthread_func(void* arg);
+void *pmtthread_func(void* arg);
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id);
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id);
+
+int test_datetime_enquiry_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t response_interval);
+
+int test_rm_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number);
+int test_rm_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *resource_ids);
+int test_rm_changed_callback(void *arg, uint8_t slot_id, uint16_t session_number);
+
+int test_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string);
+
+int test_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids);
+int test_ca_pmt_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_pmt_reply *reply, uint32_t reply_size);
+
+int test_mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t cmd_id, uint8_t delay);
+
+int test_mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t mmi_mode);
+
+int test_mmi_keypad_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t *key_codes, uint32_t key_codes_count);
+
+int test_mmi_subtitle_segment_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size);
+
+int test_mmi_scene_end_mark_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t send_scene_done, uint8_t scene_tag);
+
+int test_mmi_scene_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t scene_tag);
+
+int test_mmi_subtitle_download_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size);
+
+int test_mmi_flush_download_callback(void *arg, uint8_t slot_id, uint16_t session_number);
+
+int test_mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t blind_answer, uint8_t expected_answer_length,
+ uint8_t *text, uint32_t text_size);
+
+int test_mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw);
+
+int test_app_mmi_list_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw);
+
+struct section_ext *read_section_ext(char *buf, int buflen, int adapter, int demux, int pid, int table_id);
+
+
+
+
+
+
+
+int adapterid;
+
+int shutdown_stackthread = 0;
+int shutdown_pmtthread = 0;
+int in_menu = 0;
+int in_enq = 0;
+int ca_connected = 0;
+int pmt_pid = -1;
+int ca_session_number = 0;
+
+
+// instances of resources we actually implement here
+struct en50221_app_rm *rm_resource;
+struct en50221_app_datetime *datetime_resource;
+struct en50221_app_ai *ai_resource;
+struct en50221_app_ca *ca_resource;
+struct en50221_app_mmi *mmi_resource;
+
+// lookup table used in resource manager implementation
+struct resource {
+ struct en50221_app_public_resource_id resid;
+ uint32_t binary_resource_id;
+ en50221_sl_resource_callback callback;
+ void *arg;
+};
+struct resource resources[20];
+int resources_count = 0;
+
+// this contains all known resource ids so we can see if the cam asks for something exotic
+uint32_t resource_ids[] = { EN50221_APP_TELETEXT_RESOURCEID,
+ EN50221_APP_SMARTCARD_RESOURCEID(1),
+ EN50221_APP_RM_RESOURCEID,
+ EN50221_APP_MMI_RESOURCEID,
+ EN50221_APP_LOWSPEED_RESOURCEID(1,1),
+ EN50221_APP_EPG_RESOURCEID(1),
+ EN50221_APP_DVB_RESOURCEID,
+ EN50221_APP_CA_RESOURCEID,
+ EN50221_APP_DATETIME_RESOURCEID,
+ EN50221_APP_AUTH_RESOURCEID,
+ EN50221_APP_AI_RESOURCEID, };
+int resource_ids_count = sizeof(resource_ids)/4;
+
+
+uint16_t ai_session_numbers[5];
+
+uint16_t mmi_session_number;
+
+int main(int argc, char * argv[])
+{
+ pthread_t stackthread;
+ pthread_t pmtthread;
+ struct en50221_app_send_functions sendfuncs;
+
+ if ((argc < 2) || (argc > 3)) {
+ fprintf(stderr, "Syntax: test-app <adapterid> [<pmtpid>]\n");
+ exit(1);
+ }
+ adapterid = atoi(argv[1]);
+ if (argc == 3) {
+ if (sscanf(argv[2], "%i", &pmt_pid) != 1) {
+ fprintf(stderr, "Unable to parse PMT PID\n");
+ exit(1);
+ }
+ }
+
+ // create transport layer
+ struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ exit(1);
+ }
+
+ // find CAMs
+ int cafd;
+ if (((cafd = dvbca_open(adapterid, 0)) < 0) || (dvbca_get_cam_state(cafd, DEFAULT_SLOT) == DVBCA_CAMSTATE_MISSING)) {
+ fprintf(stderr, "Unable to open CAM on adapter %i\n", adapterid);
+ exit(1);
+ }
+
+ // reset it and wait
+ dvbca_reset(cafd, DEFAULT_SLOT);
+ printf("Found a CAM on adapter%i... waiting...\n", adapterid);
+ while(dvbca_get_cam_state(cafd, DEFAULT_SLOT) != DVBCA_CAMSTATE_READY) {
+ usleep(1000);
+ }
+
+ // register it with the CA stack
+ int slot_id = 0;
+ if ((slot_id = en50221_tl_register_slot(tl, cafd, DEFAULT_SLOT, 1000, 100)) < 0) {
+ fprintf(stderr, "Slot registration failed\n");
+ exit(1);
+ }
+ printf("slotid: %i\n", slot_id);
+
+ // create session layer
+ struct en50221_session_layer *sl = en50221_sl_create(tl, 256);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ exit(1);
+ }
+
+ // create the sendfuncs
+ sendfuncs.arg = sl;
+ sendfuncs.send_data = (en50221_send_data) en50221_sl_send_data;
+ sendfuncs.send_datav = (en50221_send_datav) en50221_sl_send_datav;
+
+ // create the resource manager resource
+ rm_resource = en50221_app_rm_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_RM_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_RM_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_rm_message;
+ resources[resources_count].arg = rm_resource;
+ en50221_app_rm_register_enq_callback(rm_resource, test_rm_enq_callback, NULL);
+ en50221_app_rm_register_reply_callback(rm_resource, test_rm_reply_callback, NULL);
+ en50221_app_rm_register_changed_callback(rm_resource, test_rm_changed_callback, NULL);
+ resources_count++;
+
+ // create the datetime resource
+ datetime_resource = en50221_app_datetime_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_DATETIME_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_DATETIME_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_datetime_message;
+ resources[resources_count].arg = datetime_resource;
+ en50221_app_datetime_register_enquiry_callback(datetime_resource, test_datetime_enquiry_callback, NULL);
+ resources_count++;
+
+ // create the application information resource
+ ai_resource = en50221_app_ai_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_AI_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_AI_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_ai_message;
+ resources[resources_count].arg = ai_resource;
+ en50221_app_ai_register_callback(ai_resource, test_ai_callback, NULL);
+ resources_count++;
+
+ // create the CA resource
+ ca_resource = en50221_app_ca_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_CA_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_CA_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_ca_message;
+ resources[resources_count].arg = ca_resource;
+ en50221_app_ca_register_info_callback(ca_resource, test_ca_info_callback, NULL);
+ en50221_app_ca_register_pmt_reply_callback(ca_resource, test_ca_pmt_reply_callback, NULL);
+ resources_count++;
+
+ // create the MMI resource
+ mmi_resource = en50221_app_mmi_create(&sendfuncs);
+ en50221_app_decode_public_resource_id(&resources[resources_count].resid, EN50221_APP_MMI_RESOURCEID);
+ resources[resources_count].binary_resource_id = EN50221_APP_MMI_RESOURCEID;
+ resources[resources_count].callback = (en50221_sl_resource_callback) en50221_app_mmi_message;
+ resources[resources_count].arg = mmi_resource;
+ en50221_app_mmi_register_close_callback(mmi_resource, test_mmi_close_callback, NULL);
+ en50221_app_mmi_register_display_control_callback(mmi_resource, test_mmi_display_control_callback, NULL);
+ en50221_app_mmi_register_keypad_control_callback(mmi_resource, test_mmi_keypad_control_callback, NULL);
+ en50221_app_mmi_register_subtitle_segment_callback(mmi_resource, test_mmi_subtitle_segment_callback, NULL);
+ en50221_app_mmi_register_scene_end_mark_callback(mmi_resource, test_mmi_scene_end_mark_callback, NULL);
+ en50221_app_mmi_register_scene_control_callback(mmi_resource, test_mmi_scene_control_callback, NULL);
+ en50221_app_mmi_register_subtitle_download_callback(mmi_resource, test_mmi_subtitle_download_callback, NULL);
+ en50221_app_mmi_register_flush_download_callback(mmi_resource, test_mmi_flush_download_callback, NULL);
+ en50221_app_mmi_register_enq_callback(mmi_resource, test_mmi_enq_callback, NULL);
+ en50221_app_mmi_register_menu_callback(mmi_resource, test_mmi_menu_callback, NULL);
+ en50221_app_mmi_register_list_callback(mmi_resource, test_app_mmi_list_callback, NULL);
+ resources_count++;
+
+ // start another thread running the stack
+ pthread_create(&stackthread, NULL, stackthread_func, tl);
+
+ // start another thread parsing PMT
+ if (pmt_pid != -1) {
+ pthread_create(&pmtthread, NULL, pmtthread_func, tl);
+ }
+
+ // register callbacks
+ en50221_sl_register_lookup_callback(sl, test_lookup_callback, sl);
+ en50221_sl_register_session_callback(sl, test_session_callback, sl);
+
+ // create a new connection on each slot
+ int tc = en50221_tl_new_tc(tl, slot_id);
+ printf("tcid: %i\n", tc);
+
+ printf("Press a key to enter menu\n");
+ getchar();
+ en50221_app_ai_entermenu(ai_resource, ai_session_numbers[slot_id]);
+
+ // wait
+ char tmp[256];
+ while(1) {
+ fgets(tmp, sizeof(tmp), stdin);
+ int choice = atoi(tmp);
+
+ if (in_menu) {
+ en50221_app_mmi_menu_answ(mmi_resource, mmi_session_number, choice);
+ in_menu = 0;
+ }
+ if (in_enq) {
+ uint32_t i;
+ uint32_t len = strlen(tmp);
+ for(i=0; i< len; i++) {
+ if (!isdigit(tmp[i])) {
+ len = i;
+ break;
+ }
+ }
+ en50221_app_mmi_answ(mmi_resource, mmi_session_number, MMI_ANSW_ID_ANSWER, (uint8_t*) tmp, len);
+ in_enq = 0;
+ }
+ }
+ printf("Press a key to exit\n");
+ getchar();
+
+ // destroy slots
+ en50221_tl_destroy_slot(tl, slot_id);
+ shutdown_stackthread = 1;
+ shutdown_pmtthread = 1;
+ pthread_join(stackthread, NULL);
+ if (pmt_pid != -1) {
+ pthread_join(pmtthread, NULL);
+ }
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ return 0;
+}
+
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id)
+{
+ struct en50221_app_public_resource_id resid;
+ (void)arg;
+
+ // decode the resource id
+ if (en50221_app_decode_public_resource_id(&resid, requested_resource_id)) {
+ printf("%02x:Public resource lookup callback %i %i %i\n", slot_id,
+ resid.resource_class, resid.resource_type, resid.resource_version);
+ } else {
+ printf("%02x:Private resource lookup callback %08x\n", slot_id, requested_resource_id);
+ return -1;
+ }
+
+ // FIXME: need better comparison
+ // FIXME: return resourceid we actually connected to
+
+ // try and find an instance of the resource
+ int i;
+ for(i=0; i<resources_count; i++) {
+ if ((resid.resource_class == resources[i].resid.resource_class) &&
+ (resid.resource_type == resources[i].resid.resource_type)) {
+ *callback_out = resources[i].callback;
+ *arg_out = resources[i].arg;
+ *connected_resource_id = resources[i].binary_resource_id;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id)
+{
+ (void)arg;
+ switch(reason) {
+ case S_SCALLBACK_REASON_CAMCONNECTING:
+ printf("%02x:CAM connecting to resource %08x, session_number %i\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_CAMCONNECTED:
+ printf("%02x:CAM successfully connected to resource %08x, session_number %i\n",
+ slot_id, resource_id, session_number);
+
+ if (resource_id == EN50221_APP_RM_RESOURCEID) {
+ en50221_app_rm_enq(rm_resource, session_number);
+ } else if (resource_id == EN50221_APP_AI_RESOURCEID) {
+ en50221_app_ai_enquiry(ai_resource, session_number);
+ } else if (resource_id == EN50221_APP_CA_RESOURCEID) {
+ en50221_app_ca_info_enq(ca_resource, session_number);
+ ca_session_number = session_number;
+ }
+
+ break;
+ case S_SCALLBACK_REASON_CAMCONNECTFAIL:
+ printf("%02x:CAM on failed to connect to resource %08x\n", slot_id, resource_id);
+ break;
+ case S_SCALLBACK_REASON_CONNECTED:
+ printf("%02x:Host connection to resource %08x connected successfully, session_number %i\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_CONNECTFAIL:
+ printf("%02x:Host connection to resource %08x failed, session_number %i\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_CLOSE:
+ printf("%02x:Connection to resource %08x, session_number %i closed\n",
+ slot_id, resource_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_TC_CONNECT:
+ printf("%02x:Host originated transport connection %i connected\n", slot_id, session_number);
+ break;
+ case S_SCALLBACK_REASON_TC_CAMCONNECT:
+ printf("%02x:CAM originated transport connection %i connected\n", slot_id, session_number);
+ break;
+ }
+ return 0;
+}
+
+
+
+int test_rm_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number)
+{
+ (void)arg;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ if (en50221_app_rm_reply(rm_resource, session_number, resource_ids_count, resource_ids)) {
+ printf("%02x:Failed to send reply to ENQ\n", slot_id);
+ }
+
+ return 0;
+}
+
+int test_rm_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *_resource_ids)
+{
+ (void)arg;
+ printf("%02x:%s\n", slot_id, __func__);
+
+ uint32_t i;
+ for(i=0; i< resource_id_count; i++) {
+ printf(" CAM provided resource id: %08x\n", _resource_ids[i]);
+ }
+
+ if (en50221_app_rm_changed(rm_resource, session_number)) {
+ printf("%02x:Failed to send REPLY\n", slot_id);
+ }
+
+ return 0;
+}
+
+int test_rm_changed_callback(void *arg, uint8_t slot_id, uint16_t session_number)
+{
+ (void)arg;
+ printf("%02x:%s\n", slot_id, __func__);
+
+ if (en50221_app_rm_enq(rm_resource, session_number)) {
+ printf("%02x:Failed to send ENQ\n", slot_id);
+ }
+
+ return 0;
+}
+
+
+
+int test_datetime_enquiry_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t response_interval)
+{
+ (void)arg;
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" response_interval:%i\n", response_interval);
+
+ if (en50221_app_datetime_send(datetime_resource, session_number, time(NULL), -1)) {
+ printf("%02x:Failed to send datetime\n", slot_id);
+ }
+
+ return 0;
+}
+
+
+
+int test_ai_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t application_type, uint16_t application_manufacturer,
+ uint16_t manufacturer_code, uint8_t menu_string_length,
+ uint8_t *menu_string)
+{
+ (void)arg;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" Application type: %02x\n", application_type);
+ printf(" Application manufacturer: %04x\n", application_manufacturer);
+ printf(" Manufacturer code: %04x\n", manufacturer_code);
+ printf(" Menu string: %.*s\n", menu_string_length, menu_string);
+
+ ai_session_numbers[slot_id] = session_number;
+
+ return 0;
+}
+
+
+
+int test_ca_info_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ uint32_t i;
+ for(i=0; i< ca_id_count; i++) {
+ printf(" Supported CA ID: %04x\n", ca_ids[i]);
+ }
+
+ ca_connected = 1;
+ return 0;
+}
+
+int test_ca_pmt_reply_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_pmt_reply *reply, uint32_t reply_size)
+{
+ (void)arg;
+ (void)session_number;
+ (void)reply;
+ (void)reply_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+
+int test_mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t cmd_id, uint8_t delay)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" cmd_id: %02x\n", cmd_id);
+ printf(" delay: %02x\n", delay);
+
+ return 0;
+}
+
+int test_mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t mmi_mode)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" cmd_id: %02x\n", cmd_id);
+ printf(" mode: %02x\n", mmi_mode);
+
+ if (cmd_id == MMI_DISPLAY_CONTROL_CMD_ID_SET_MMI_MODE) {
+ struct en50221_app_mmi_display_reply_details details;
+
+ details.u.mode_ack.mmi_mode = mmi_mode;
+ if (en50221_app_mmi_display_reply(mmi_resource, session_number, MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK, &details)) {
+ printf("%02x:Failed to send mode ack\n", slot_id);
+ }
+ }
+
+ return 0;
+}
+
+int test_mmi_keypad_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t cmd_id, uint8_t *key_codes, uint32_t key_codes_count)
+{
+ (void)arg;
+ (void)session_number;
+ (void)cmd_id;
+ (void)key_codes;
+ (void)key_codes_count;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_subtitle_segment_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size)
+{
+ (void)arg;
+ (void)session_number;
+ (void)segment;
+ (void)segment_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_scene_end_mark_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t send_scene_done, uint8_t scene_tag)
+{
+ (void)arg;
+ (void)session_number;
+ (void)decoder_continue_flag;
+ (void)scene_reveal_flag;
+ (void)send_scene_done;
+ (void)scene_tag;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_scene_control_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
+ uint8_t scene_tag)
+{
+ (void)arg;
+ (void)session_number;
+ (void)decoder_continue_flag;
+ (void)scene_reveal_flag;
+ (void)scene_tag;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_subtitle_download_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t *segment, uint32_t segment_size)
+{
+ (void)arg;
+ (void)session_number;
+ (void)segment;
+ (void)segment_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_flush_download_callback(void *arg, uint8_t slot_id, uint16_t session_number)
+{
+ (void)arg;
+ (void)session_number;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ return 0;
+}
+
+int test_mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ uint8_t blind_answer, uint8_t expected_answer_length,
+ uint8_t *text, uint32_t text_size)
+{
+ (void)arg;
+ (void)text;
+ (void)text_size;
+
+ printf("%02x:%s\n", slot_id, __func__);
+ printf(" blind: %i\n", blind_answer);
+ printf(" expected_answer_length: %i\n", expected_answer_length);
+
+ mmi_session_number = session_number;
+ in_enq = 1;
+
+ return 0;
+}
+
+int test_mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw)
+{
+ (void)arg;
+ (void)items_raw;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ printf(" title: %.*s\n", title->text_length, title->text);
+ printf(" sub_title: %.*s\n", sub_title->text_length, sub_title->text);
+ printf(" bottom: %.*s\n", bottom->text_length, bottom->text);
+
+ uint32_t i;
+ for(i=0; i< item_count; i++) {
+ printf(" item %i: %.*s\n", i+1, items[i].text_length, items[i].text);
+ }
+ printf(" raw_length: %i\n", item_raw_length);
+
+ mmi_session_number = session_number;
+ in_menu = 1;
+
+ return 0;
+}
+
+int test_app_mmi_list_callback(void *arg, uint8_t slot_id, uint16_t session_number,
+ struct en50221_app_mmi_text *title,
+ struct en50221_app_mmi_text *sub_title,
+ struct en50221_app_mmi_text *bottom,
+ uint32_t item_count, struct en50221_app_mmi_text *items,
+ uint32_t item_raw_length, uint8_t *items_raw)
+{
+ (void)arg;
+ (void)items_raw;
+ (void)arg;
+
+ printf("%02x:%s\n", slot_id, __func__);
+
+ printf(" title: %.*s\n", title->text_length, title->text);
+ printf(" sub_title: %.*s\n", sub_title->text_length, sub_title->text);
+ printf(" bottom: %.*s\n", bottom->text_length, bottom->text);
+
+ uint32_t i;
+ for(i=0; i< item_count; i++) {
+ printf(" item %i: %.*s\n", i+1, items[i].text_length, items[i].text);
+ }
+ printf(" raw_length: %i\n", item_raw_length);
+
+ mmi_session_number = session_number;
+ in_menu = 1;
+
+ return 0;
+}
+
+
+
+
+
+
+
+void *stackthread_func(void* arg) {
+ struct en50221_transport_layer *tl = arg;
+ int lasterror = 0;
+
+ while(!shutdown_stackthread) {
+ int error;
+ if ((error = en50221_tl_poll(tl)) != 0) {
+ if (error != lasterror) {
+ fprintf(stderr, "Error reported by stack slot:%i error:%i\n",
+ en50221_tl_get_error_slot(tl),
+ en50221_tl_get_error(tl));
+ }
+ lasterror = error;
+ }
+ }
+
+ shutdown_stackthread = 0;
+ return 0;
+}
+
+void *pmtthread_func(void* arg) {
+ (void)arg;
+ char buf[4096];
+ uint8_t capmt[4096];
+ int pmtversion = -1;
+
+ while(!shutdown_pmtthread) {
+
+ if (!ca_connected) {
+ sleep(1);
+ continue;
+ }
+
+ // read the PMT
+ struct section_ext *section_ext = read_section_ext(buf, sizeof(buf), adapterid, 0, pmt_pid, stag_mpeg_program_map);
+ if (section_ext == NULL) {
+ fprintf(stderr, "Failed to read PMT\n");
+ exit(1);
+ }
+ struct mpeg_pmt_section *pmt = mpeg_pmt_section_codec(section_ext);
+ if (pmt == NULL) {
+ fprintf(stderr, "Bad PMT received\n");
+ exit(1);
+ }
+ if (pmt->head.version_number == pmtversion) {
+ continue;
+ }
+
+ // translate it into a CA PMT
+ int listmgmt = CA_LIST_MANAGEMENT_ONLY;
+ if (pmtversion != -1) {
+ listmgmt = CA_LIST_MANAGEMENT_UPDATE;
+ }
+ int size;
+ if ((size = en50221_ca_format_pmt(pmt,
+ capmt,
+ sizeof(capmt),
+ listmgmt,
+ 0,
+ CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
+ fprintf(stderr, "Failed to format CA PMT object\n");
+ exit(1);
+ }
+
+ // set it
+ if (en50221_app_ca_pmt(ca_resource, ca_session_number, capmt, size)) {
+ fprintf(stderr, "Failed to send CA PMT object\n");
+ exit(1);
+ }
+ pmtversion = pmt->head.version_number;
+ }
+ shutdown_pmtthread = 0;
+ return 0;
+}
+
+
+struct section_ext *read_section_ext(char *buf, int buflen, int adapter, int demux, int pid, int table_id)
+{
+ int demux_fd = -1;
+ uint8_t filter[18];
+ uint8_t mask[18];
+ int size;
+ struct section *section;
+ struct section_ext *result = NULL;
+
+ // open the demuxer
+ if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
+ goto exit;
+ }
+
+ // create a section filter
+ memset(filter, 0, sizeof(filter));
+ memset(mask, 0, sizeof(mask));
+ filter[0] = table_id;
+ mask[0] = 0xFF;
+ if (dvbdemux_set_section_filter(demux_fd, pid, filter, mask, 1, 1)) {
+ goto exit;
+ }
+
+ // read the section
+ if ((size = read(demux_fd, buf, buflen)) < 0) {
+ goto exit;
+ }
+
+ // parse it as a section
+ section = section_codec((uint8_t*) buf, size);
+ if (section == NULL) {
+ goto exit;
+ }
+
+ // parse it as a section_ext
+ result = section_ext_decode(section, 0);
+
+exit:
+ if (demux_fd != -1)
+ close(demux_fd);
+ return result;
+}
diff --git a/test/libdvben50221/test-session.c b/test/libdvben50221/test-session.c
new file mode 100644
index 0000000..14dc13e
--- /dev/null
+++ b/test/libdvben50221/test-session.c
@@ -0,0 +1,171 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <libdvben50221/en50221_session.h>
+#include <libdvben50221/en50221_app_utils.h>
+#include <libdvbapi/dvbca.h>
+#include <pthread.h>
+
+void *stackthread_func(void* arg);
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id);
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id);
+
+
+int shutdown_stackthread = 0;
+
+#define DEFAULT_SLOT 0
+
+int main(int argc, char * argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ int i;
+ pthread_t stackthread;
+
+ // create transport layer
+ struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ exit(1);
+ }
+
+ // find CAMs
+ int slot_count = 0;
+ int cafd= -1;
+ for(i=0; i<20; i++) {
+ if ((cafd = dvbca_open(i, 0)) > 0) {
+ if (dvbca_get_cam_state(cafd, DEFAULT_SLOT) == DVBCA_CAMSTATE_MISSING) {
+ close(cafd);
+ continue;
+ }
+
+ // reset it and wait
+ dvbca_reset(cafd, DEFAULT_SLOT);
+ printf("Found a CAM on adapter%i... waiting...\n", i);
+ while(dvbca_get_cam_state(cafd, DEFAULT_SLOT) != DVBCA_CAMSTATE_READY) {
+ usleep(1000);
+ }
+
+ // register it with the CA stack
+ int slot_id = 0;
+ if ((slot_id = en50221_tl_register_slot(tl, cafd, DEFAULT_SLOT, 1000, 100)) < 0) {
+ fprintf(stderr, "Slot registration failed\n");
+ exit(1);
+ }
+ printf("slotid: %i\n", slot_id);
+ slot_count++;
+ }
+ }
+
+ // create session layer
+ struct en50221_session_layer *sl = en50221_sl_create(tl, 256);
+ if (sl == NULL) {
+ fprintf(stderr, "Failed to create session layer\n");
+ exit(1);
+ }
+
+ // start another thread running the stack
+ pthread_create(&stackthread, NULL, stackthread_func, tl);
+
+ // register callbacks
+ en50221_sl_register_lookup_callback(sl, test_lookup_callback, sl);
+ en50221_sl_register_session_callback(sl, test_session_callback, sl);
+
+ // create a new connection
+ for(i=0; i<slot_count; i++) {
+ int tc = en50221_tl_new_tc(tl, i);
+ printf("tcid: %i\n", tc);
+ }
+
+ // wait
+ printf("Press a key to exit\n");
+ getchar();
+
+ // destroy slots
+ for(i=0; i<slot_count; i++) {
+ en50221_tl_destroy_slot(tl, i);
+ }
+ shutdown_stackthread = 1;
+ pthread_join(stackthread, NULL);
+
+ // destroy session layer
+ en50221_sl_destroy(sl);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ return 0;
+}
+
+int test_lookup_callback(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
+ en50221_sl_resource_callback *callback_out, void **arg_out, uint32_t *connected_resource_id)
+{
+ (void)arg;
+ (void)callback_out;
+ (void)arg_out;
+ (void)connected_resource_id;
+
+ struct en50221_app_public_resource_id resid;
+
+ if (en50221_app_decode_public_resource_id(&resid, requested_resource_id)) {
+ printf("Public resource lookup callback %i %i %i %i\n", slot_id,
+ resid.resource_class, resid.resource_type, resid.resource_version);
+ } else {
+ printf("Private resource lookup callback %i %08x\n", slot_id, requested_resource_id);
+ }
+
+ return -1;
+}
+
+int test_session_callback(void *arg, int reason, uint8_t slot_id, uint16_t session_number, uint32_t resource_id)
+{
+ (void)arg;
+
+ printf("Session callback %i %i %i %04x\n", slot_id, session_number, reason, resource_id);
+
+ return -1;
+}
+
+void *stackthread_func(void* arg) {
+ struct en50221_transport_layer *tl = arg;
+ int lasterror = 0;
+
+ while(!shutdown_stackthread) {
+ int error;
+ if ((error = en50221_tl_poll(tl)) != 0) {
+ if (error != lasterror) {
+ fprintf(stderr, "Error reported by stack slot:%i error:%i\n",
+ en50221_tl_get_error_slot(tl),
+ en50221_tl_get_error(tl));
+ }
+ lasterror = error;
+ }
+ }
+
+ shutdown_stackthread = 0;
+ return 0;
+}
diff --git a/test/libdvben50221/test-transport.c b/test/libdvben50221/test-transport.c
new file mode 100644
index 0000000..fdfd98a
--- /dev/null
+++ b/test/libdvben50221/test-transport.c
@@ -0,0 +1,144 @@
+/*
+ en50221 encoder An implementation for libdvb
+ an implementation for the en50221 transport layer
+
+ Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+ Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
+ Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <libdvben50221/en50221_transport.h>
+#include <libdvbapi/dvbca.h>
+#include <pthread.h>
+
+void *stackthread_func(void* arg);
+void test_callback(void *arg, int reason,
+ uint8_t *data, uint32_t data_length,
+ uint8_t slot_id, uint8_t connection_id);
+
+int shutdown_stackthread = 0;
+
+#define DEFAULT_SLOT 0
+
+int main(int argc, char * argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ int i;
+ pthread_t stackthread;
+
+ // create transport layer
+ struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
+ if (tl == NULL) {
+ fprintf(stderr, "Failed to create transport layer\n");
+ exit(1);
+ }
+
+ // find CAMs
+ int slot_count = 0;
+ int cafd= -1;
+ for(i=0; i<20; i++) {
+ if ((cafd = dvbca_open(i, 0)) > 0) {
+ if (dvbca_get_cam_state(cafd, DEFAULT_SLOT) == DVBCA_CAMSTATE_MISSING) {
+ close(cafd);
+ continue;
+ }
+
+ // reset it and wait
+ dvbca_reset(cafd, DEFAULT_SLOT);
+ printf("Found a CAM on adapter%i... waiting...\n", i);
+ while(dvbca_get_cam_state(cafd, DEFAULT_SLOT) != DVBCA_CAMSTATE_READY) {
+ usleep(1000);
+ }
+
+ // register it with the CA stack
+ int slot_id = 0;
+ if ((slot_id = en50221_tl_register_slot(tl, cafd, DEFAULT_SLOT, 1000, 100)) < 0) {
+ fprintf(stderr, "Slot registration failed\n");
+ exit(1);
+ }
+ printf("slotid: %i\n", slot_id);
+ slot_count++;
+ }
+ }
+
+ // start another thread to running the stack
+ pthread_create(&stackthread, NULL, stackthread_func, tl);
+
+ // register callback
+ en50221_tl_register_callback(tl, test_callback, tl);
+
+ // create a new connection
+ for(i=0; i<slot_count; i++) {
+ int tc = en50221_tl_new_tc(tl, i);
+ printf("tcid: %i\n", tc);
+ }
+
+ // wait
+ printf("Press a key to exit\n");
+ getchar();
+
+ // destroy slots
+ for(i=0; i<slot_count; i++) {
+ en50221_tl_destroy_slot(tl, i);
+ }
+ shutdown_stackthread = 1;
+ pthread_join(stackthread, NULL);
+
+ // destroy transport layer
+ en50221_tl_destroy(tl);
+
+ return 0;
+}
+
+void test_callback(void *arg, int reason,
+ uint8_t *data, uint32_t data_length,
+ uint8_t slot_id, uint8_t connection_id)
+{
+ (void) arg;
+
+ printf("-----------------------------------\n");
+ printf("CALLBACK SLOTID:%i %i %i\n", slot_id, connection_id, reason);
+
+ uint32_t i;
+ for(i=0; i< data_length; i++) {
+ printf("%02x %02x\n", i, data[i]);
+ }
+}
+
+void *stackthread_func(void* arg) {
+ struct en50221_transport_layer *tl = arg;
+ int lasterror = 0;
+
+ while(!shutdown_stackthread) {
+ int error;
+ if ((error = en50221_tl_poll(tl)) != 0) {
+ if (error != lasterror) {
+ fprintf(stderr, "Error reported by stack slot:%i error:%i\n",
+ en50221_tl_get_error_slot(tl),
+ en50221_tl_get_error(tl));
+ }
+ lasterror = error;
+ }
+ }
+
+ shutdown_stackthread = 0;
+ return 0;
+}
diff --git a/test/libdvbsec/Makefile b/test/libdvbsec/Makefile
new file mode 100644
index 0000000..27c9c21
--- /dev/null
+++ b/test/libdvbsec/Makefile
@@ -0,0 +1,12 @@
+# Makefile for linuxtv.org dvb-apps/test/libdvbsec
+
+binaries = dvbsec_test
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbsec/libdvbsec.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libdvbsec/dvbsec_test.c b/test/libdvbsec/dvbsec_test.c
new file mode 100644
index 0000000..b49d703
--- /dev/null
+++ b/test/libdvbsec/dvbsec_test.c
@@ -0,0 +1,85 @@
+/**
+ * dvbsec testing.
+ *
+ * Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libdvbsec/dvbsec_cfg.h>
+
+void syntax(void);
+
+struct dvbsec_config *secconfigs = NULL;
+int seccount = 0;
+
+int secload_callback(void *private, struct dvbsec_config *sec);
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4) {
+ syntax();
+ }
+
+ if (!strcmp(argv[1], "-sec")) {
+
+ FILE *f = fopen(argv[2], "r");
+ if (!f) {
+ fprintf(stderr, "Unable to load %s\n", argv[2]);
+ exit(1);
+ }
+ dvbsec_cfg_load(f, NULL, secload_callback);
+ fclose(f);
+
+ f = fopen(argv[3], "w");
+ if (!f) {
+ fprintf(stderr, "Unable to write %s\n", argv[3]);
+ exit(1);
+ }
+ dvbsec_cfg_save(f, secconfigs, seccount);
+ fclose(f);
+
+ } else {
+ syntax();
+ }
+
+ exit(0);
+}
+
+int secload_callback(void *private, struct dvbsec_config *sec)
+{
+ (void) private;
+
+ struct dvbsec_config *tmp = realloc(secconfigs, (seccount+1) * sizeof(struct dvbsec_config));
+ if (tmp == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ secconfigs = tmp;
+
+ memcpy(&secconfigs[seccount++], sec, sizeof(struct dvbsec_config));
+
+ return 0;
+}
+
+void syntax()
+{
+ fprintf(stderr,
+ "Syntax: dvbcfg_test <-zapchannel|-sec> <input filename> <output filename>\n");
+ exit(1);
+}
diff --git a/test/libdvbsec/test_sec.txt b/test/libdvbsec/test_sec.txt
new file mode 100644
index 0000000..1189026
--- /dev/null
+++ b/test/libdvbsec/test_sec.txt
@@ -0,0 +1,28 @@
+[sec]
+name=test1
+switch-frequency=100000
+lof-lo-v=20
+lof-lo-h=30
+lof-lo-l=40
+lof-lo-r=50
+lof-hi-v=60
+lof-hi-h=70
+lof-hi-l=80
+lof-hi-r=90
+config-type=none
+
+[sec]
+name=test2
+switch-frequency=200
+lof-lo-v=40
+lof-hi-h=50
+config-type=simple
+
+[sec]
+name=test3
+switch-frequency=100000
+lof-lo-l=20
+lof-hi-r=30
+config-type=advanced
+cmd-lo-v=MOOVH
+cmd-lo-h=MOOLH
diff --git a/test/libesg/Makefile b/test/libesg/Makefile
new file mode 100644
index 0000000..11d65bd
--- /dev/null
+++ b/test/libesg/Makefile
@@ -0,0 +1,12 @@
+# Makefile for linuxtv.org dvb-apps/test/libucsi
+
+binaries = testesg
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libesg/libesg.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libesg/samples/ESGProviderDiscoveryDescriptor.xml b/test/libesg/samples/ESGProviderDiscoveryDescriptor.xml
new file mode 100644
index 0000000..3989afb
--- /dev/null
+++ b/test/libesg/samples/ESGProviderDiscoveryDescriptor.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<ESGProviderDiscovery xmlns="urn:dvb:ipdc:esgbs:2005" xmlns:mpeg7="urn:mpeg:mpeg7:schema:2001">
+ <ServiceProvider>
+ <ProviderURI>http://www.sidsa.com</ProviderURI>
+ <ProviderName>SIDSA (Multiple Stream)</ProviderName>
+ <ProviderID>1</ProviderID>
+ </ServiceProvider>
+ <ServiceProvider>
+ <ProviderURI>http://www.sidsa.com</ProviderURI>
+ <ProviderName>SIDSA (Single Stream)</ProviderName>
+ <ProviderID>2</ProviderID>
+ </ServiceProvider>
+</ESGProviderDiscovery>
diff --git a/test/libesg/testesg.c b/test/libesg/testesg.c
new file mode 100644
index 0000000..f2183ac
--- /dev/null
+++ b/test/libesg/testesg.c
@@ -0,0 +1,563 @@
+/*
+ * ESG parser
+ *
+ * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <libesg/bootstrap/access_descriptor.h>
+#include <libesg/encapsulation/container.h>
+#include <libesg/encapsulation/fragment_management_information.h>
+#include <libesg/encapsulation/data_repository.h>
+#include <libesg/encapsulation/string_repository.h>
+#include <libesg/representation/encapsulated_textual_esg_xml_fragment.h>
+#include <libesg/representation/init_message.h>
+#include <libesg/representation/textual_decoder_init.h>
+#include <libesg/representation/bim_decoder_init.h>
+#include <libesg/transport/session_partition_declaration.h>
+
+#define MAX_FILENAME 256
+
+void usage(void) {
+ static const char *_usage =
+ "Usage: testesg [-a <ESGAccessDescriptor>]\n"
+ " [-c <ESGContainer with Textual ESG XML Fragment>]\n"
+ " [-X XXXX]\n";
+
+ fprintf(stderr, "%s", _usage);
+ exit(1);
+}
+
+void read_from_file(const char *filename, char **buffer, int *size) {
+ int fd;
+ struct stat fs;
+
+ if ((fd = open(filename, O_RDONLY)) <= 0) {
+ fprintf(stderr, "File not found\n");
+ exit(1);
+ }
+
+ if (fstat(fd, &fs) < 0) {
+ fprintf(stderr, "File not readable\n");
+ exit(1);
+ }
+ *size = fs.st_size;
+
+ *buffer = (char *) malloc(*size);
+ if (read(fd, *buffer, *size) != *size) {
+ fprintf(stderr, "File read error\n");
+ exit(1);
+ }
+
+ close(fd);
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ char access_descriptor_filename[MAX_FILENAME] = "";
+ char container_filename[MAX_FILENAME] = "";
+ int c;
+ char *buffer = NULL;
+ int size;
+
+ // Read command line options
+ while ((c = getopt(argc, argv, "a:c:")) != -1) {
+ switch (c) {
+ case 'a':
+ strncpy(access_descriptor_filename, optarg, MAX_FILENAME);
+ break;
+ case 'c':
+ strncpy(container_filename, optarg, MAX_FILENAME);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ // ESGAccessDescriptor
+ if (strncmp(access_descriptor_filename, "", MAX_FILENAME) != 0) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "Reading ESG Access Descriptor = %s\n", access_descriptor_filename);
+ fprintf(stdout, "**************************************************\n\n");
+
+ read_from_file(access_descriptor_filename, &buffer, &size);
+
+ struct esg_access_descriptor *access_descriptor = esg_access_descriptor_decode((uint8_t *) buffer, size);
+ free(buffer);
+ if (access_descriptor == NULL) {
+ fprintf(stderr, "ESG Access Descriptor decode error\n");
+ exit(1);
+ }
+ fprintf(stdout, "n_o_ESGEntries %d\n\n", access_descriptor->n_o_entries);
+
+ struct esg_entry *entry;
+ esg_access_descriptor_entry_list_for_each(access_descriptor, entry) {
+ fprintf(stdout, " ESGEntryVersion %d\n", entry->version);
+ fprintf(stdout, " MultipleStreamTransport %d\n", entry->multiple_stream_transport);
+ fprintf(stdout, " IPVersion6 %d\n", entry->ip_version_6);
+ fprintf(stdout, " ProviderID %d\n", entry->provider_id);
+ if (entry->ip_version_6 == 0) {
+ fprintf(stdout, " SourceIPAddress %d.%d.%d.%d\n",
+ entry->source_ip.ipv4[0],
+ entry->source_ip.ipv4[1],
+ entry->source_ip.ipv4[2],
+ entry->source_ip.ipv4[3]);
+ fprintf(stdout, " DestinationIPAddress %d.%d.%d.%d\n",
+ entry->destination_ip.ipv4[0],
+ entry->destination_ip.ipv4[1],
+ entry->destination_ip.ipv4[2],
+ entry->destination_ip.ipv4[3]);
+ } else if (entry->ip_version_6 == 1) {
+ fprintf(stdout, " SourceIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ entry->source_ip.ipv6[0],
+ entry->source_ip.ipv6[1],
+ entry->source_ip.ipv6[2],
+ entry->source_ip.ipv6[3],
+ entry->source_ip.ipv6[4],
+ entry->source_ip.ipv6[5],
+ entry->source_ip.ipv6[6],
+ entry->source_ip.ipv6[7],
+ entry->source_ip.ipv6[8],
+ entry->source_ip.ipv6[9],
+ entry->source_ip.ipv6[10],
+ entry->source_ip.ipv6[11],
+ entry->source_ip.ipv6[12],
+ entry->source_ip.ipv6[13],
+ entry->source_ip.ipv6[14],
+ entry->source_ip.ipv6[15]);
+ fprintf(stdout, " DestinationIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ entry->destination_ip.ipv6[0],
+ entry->destination_ip.ipv6[1],
+ entry->destination_ip.ipv6[2],
+ entry->destination_ip.ipv6[3],
+ entry->destination_ip.ipv6[4],
+ entry->destination_ip.ipv6[5],
+ entry->destination_ip.ipv6[6],
+ entry->destination_ip.ipv6[7],
+ entry->destination_ip.ipv6[8],
+ entry->destination_ip.ipv6[9],
+ entry->destination_ip.ipv6[10],
+ entry->destination_ip.ipv6[11],
+ entry->destination_ip.ipv6[12],
+ entry->destination_ip.ipv6[13],
+ entry->destination_ip.ipv6[14],
+ entry->destination_ip.ipv6[15]);
+ }
+ fprintf(stdout, "Port %d\n", entry->port);
+ fprintf(stdout, "TSI %d\n", entry->tsi);
+ fprintf(stdout, "\n");
+ }
+ }
+
+ // ESGContainer
+ if (strncmp(container_filename, "", MAX_FILENAME) != 0) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "Reading ESG Container = %s\n", container_filename);
+ fprintf(stdout, "**************************************************\n\n");
+
+ read_from_file(container_filename, &buffer, &size);
+
+ struct esg_container *container = esg_container_decode((uint8_t *) buffer, size);
+ free(buffer);
+ if (container == NULL) {
+ fprintf(stderr, "ESG Container decode error\n");
+ exit(1);
+ }
+ if (container->header == NULL) {
+ fprintf(stderr, "ESG Container no header found\n");
+ exit(1);
+ }
+
+ struct esg_encapsulation_structure *fragment_management_information = NULL;
+ struct esg_data_repository *data_repository = NULL;
+ struct esg_string_repository *string_repository = NULL;
+ struct esg_container_structure *structure = NULL;
+ struct esg_init_message *init_message = NULL;
+ struct esg_textual_encoding_parameters *textual_encoding_parameters = NULL;
+ struct esg_textual_decoder_init *textual_decoder_init = NULL;
+ struct esg_namespace_prefix *namespace_prefix = NULL;
+ struct esg_xml_fragment_type *xml_fragment_type = NULL;
+ struct esg_bim_encoding_parameters *bim_encoding_parameters = NULL;
+ struct esg_bim_decoder_init *bim_decoder_init = NULL;
+ struct esg_session_partition_declaration *partition = NULL;
+ struct esg_session_field *field = NULL;
+ struct esg_session_ip_stream *ip_stream = NULL;
+ struct esg_session_ip_stream_field *ip_stream_field = NULL;
+ esg_container_header_structure_list_for_each(container->header, structure) {
+ fprintf(stdout, " structure_type %d [0x%02x]\n", structure->type, structure->type);
+ fprintf(stdout, " structure_id %d [0x%02x]\n", structure->id, structure->id);
+ fprintf(stdout, " structure_ptr %d\n", structure->ptr);
+ fprintf(stdout, " structure_length %d\n\n", structure->length);
+ switch (structure->type) {
+ case 0x01: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG Fragment Management Information\n");
+
+ fragment_management_information = (struct esg_encapsulation_structure *) structure->data;
+ if (fragment_management_information == NULL) {
+ fprintf(stderr, "ESG Fragment Management Information decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, " fragment_reference_format %d [0x%02x]\n\n", fragment_management_information->header->fragment_reference_format, fragment_management_information->header->fragment_reference_format);
+
+ struct esg_encapsulation_entry *entry;
+ esg_encapsulation_structure_entry_list_for_each(fragment_management_information, entry) {
+ fprintf(stdout, " fragment_type %d [0x%02x]\n", entry->fragment_reference->fragment_type, entry->fragment_reference->fragment_type);
+ fprintf(stdout, " data_repository_offset %d\n", entry->fragment_reference->data_repository_offset);
+ fprintf(stdout, " fragment_version %d\n", entry->fragment_version);
+ fprintf(stdout, " fragment_id %d\n\n", entry->fragment_id);
+ }
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0x02: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG String Repository / ");
+
+ string_repository = (struct esg_string_repository *) structure->data;
+ if (string_repository == NULL) {
+ fprintf(stderr, "ESG String Repository decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, "encoding_type %d / length %d\n\n", string_repository->encoding_type, string_repository->length);
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0x03: {
+ //TODO
+ break;
+ }
+ case 0x04: {
+ //TODO
+ break;
+ }
+ case 0x05: {
+ //TODO
+ break;
+ }
+ case 0xE0: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG Data Repository / ");
+
+ data_repository = (struct esg_data_repository *) structure->data;
+ if (data_repository == NULL) {
+ fprintf(stderr, "ESG Data Repository decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, "length %d\n\n", data_repository->length);
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0xE1: {
+ switch (structure->id) {
+ case 0xFF: {
+ fprintf(stdout, " ESG Session Partition Declaration\n");
+
+ partition = (struct esg_session_partition_declaration *) structure->data;
+ fprintf(stdout, " num_fields %d\n", partition->num_fields);
+ fprintf(stdout, " overlapping %d\n\n", partition->overlapping);
+ esg_session_partition_declaration_field_list_for_each(partition, field) {
+ fprintf(stdout, " identifier %d\n", field->identifier);
+ fprintf(stdout, " encoding %d\n",field->encoding);
+ fprintf(stdout, " length %d\n\n",field->length);
+ }
+ fprintf(stdout, " n_o_IPStreams %d\n", partition->n_o_ip_streams);
+ fprintf(stdout, " IPVersion6 %d\n\n", partition->ip_version_6);
+ esg_session_partition_declaration_ip_stream_list_for_each(partition, ip_stream) {
+ fprintf(stdout, " IPStreamID %d\n", ip_stream->id);
+ if (partition->ip_version_6 == 0) {
+ fprintf(stdout, " SourceIPAddress %d.%d.%d.%d\n",
+ ip_stream->source_ip.ipv4[0],
+ ip_stream->source_ip.ipv4[1],
+ ip_stream->source_ip.ipv4[2],
+ ip_stream->source_ip.ipv4[3]);
+ fprintf(stdout, " DestinationIPAddress %d.%d.%d.%d\n",
+ ip_stream->destination_ip.ipv4[0],
+ ip_stream->destination_ip.ipv4[1],
+ ip_stream->destination_ip.ipv4[2],
+ ip_stream->destination_ip.ipv4[3]);
+ } else if (partition->ip_version_6 == 1) {
+ fprintf(stdout, " SourceIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ ip_stream->source_ip.ipv6[0],
+ ip_stream->source_ip.ipv6[1],
+ ip_stream->source_ip.ipv6[2],
+ ip_stream->source_ip.ipv6[3],
+ ip_stream->source_ip.ipv6[4],
+ ip_stream->source_ip.ipv6[5],
+ ip_stream->source_ip.ipv6[6],
+ ip_stream->source_ip.ipv6[7],
+ ip_stream->source_ip.ipv6[8],
+ ip_stream->source_ip.ipv6[9],
+ ip_stream->source_ip.ipv6[10],
+ ip_stream->source_ip.ipv6[11],
+ ip_stream->source_ip.ipv6[12],
+ ip_stream->source_ip.ipv6[13],
+ ip_stream->source_ip.ipv6[14],
+ ip_stream->source_ip.ipv6[15]);
+ fprintf(stdout, " DestinationIPAddress %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ ip_stream->destination_ip.ipv6[0],
+ ip_stream->destination_ip.ipv6[1],
+ ip_stream->destination_ip.ipv6[2],
+ ip_stream->destination_ip.ipv6[3],
+ ip_stream->destination_ip.ipv6[4],
+ ip_stream->destination_ip.ipv6[5],
+ ip_stream->destination_ip.ipv6[6],
+ ip_stream->destination_ip.ipv6[7],
+ ip_stream->destination_ip.ipv6[8],
+ ip_stream->destination_ip.ipv6[9],
+ ip_stream->destination_ip.ipv6[10],
+ ip_stream->destination_ip.ipv6[11],
+ ip_stream->destination_ip.ipv6[12],
+ ip_stream->destination_ip.ipv6[13],
+ ip_stream->destination_ip.ipv6[14],
+ ip_stream->destination_ip.ipv6[15]);
+ }
+ fprintf(stdout, " Port %d\n", ip_stream->port);
+ fprintf(stdout, " SessionID %d\n", ip_stream->session_id);
+
+ field = partition->field_list;
+ esg_session_ip_stream_field_list_for_each(ip_stream, ip_stream_field) {
+ switch (field->encoding) {
+ case 0x0000: {
+ if (ip_stream_field->start_field_value != NULL) {
+ fprintf(stdout, " start_field_value %s\n", ip_stream_field->start_field_value->string);
+ }
+ fprintf(stdout, " end_field_value %s\n", ip_stream_field->end_field_value->string);
+ break;
+ }
+ case 0x0101: {
+ if (ip_stream_field->start_field_value != NULL) {
+ fprintf(stdout, " start_field_value %d\n", ip_stream_field->start_field_value->unsigned_short);
+ }
+ fprintf(stdout, " end_field_value %d\n", ip_stream_field->end_field_value->unsigned_short);
+ break;
+ }
+ }
+
+ field = field->_next;
+ }
+ fprintf(stdout, "\n");
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ case 0xE2: {
+ switch (structure->id) {
+ case 0x00: {
+ fprintf(stdout, " ESG Init Message\n");
+
+ init_message = (struct esg_init_message *) structure->data;
+ if (init_message == NULL) {
+ fprintf(stderr, "ESG Init Message decode error\n");
+ exit(1);
+ }
+
+ fprintf(stdout, " EncodingVersion %d [0x%02x]\n", init_message->encoding_version, init_message->encoding_version);
+ fprintf(stdout, " IndexingFlag %d\n", init_message->indexing_flag);
+ fprintf(stdout, " DecoderInitptr %d\n", init_message->decoder_init_ptr);
+ if (init_message->indexing_flag) {
+ fprintf(stdout, " IndexingVersion %d\n", init_message->indexing_version);
+ }
+
+ switch (init_message->encoding_version) {
+ case 0xF1: {
+ bim_encoding_parameters = (struct esg_bim_encoding_parameters *) init_message->encoding_parameters;
+ if (bim_encoding_parameters == NULL) {
+ fprintf(stderr, "ESG Init Message decode error / bim_encoding_parameters\n");
+ exit(1);
+ }
+ fprintf(stdout, " BufferSizeFlag %d\n", bim_encoding_parameters->buffer_size_flag);
+ fprintf(stdout, " PositionCodeFlag %d\n", bim_encoding_parameters->position_code_flag);
+ fprintf(stdout, " CharacterEncoding %d\n", bim_encoding_parameters->character_encoding);
+ if (bim_encoding_parameters->buffer_size_flag) {
+ fprintf(stdout, " BufferSize %d\n", bim_encoding_parameters->buffer_size);
+ }
+
+ // TODO BimDecoderInit
+ break;
+ }
+ case 0xF2:
+ case 0xF3: {
+ textual_encoding_parameters = (struct esg_textual_encoding_parameters *) init_message->encoding_parameters;
+ if (textual_encoding_parameters == NULL) {
+ fprintf(stderr, "ESG Init Message decode error / textual_encoding_parameters\n");
+ exit(1);
+ }
+ fprintf(stdout, " CharacterEncoding %d\n\n", textual_encoding_parameters->character_encoding);
+
+ // TextualDecoderInit
+ textual_decoder_init = (struct esg_textual_decoder_init *) init_message->decoder_init;
+ if (textual_decoder_init == NULL) {
+ fprintf(stderr, "ESG Init Message decode error / textual_decoder_init\n");
+ exit(1);
+ }
+ fprintf(stdout, " Textual DecoderInit\n");
+ fprintf(stdout, " num_namespaces_prefixes %d\n\n", textual_decoder_init->num_namespace_prefixes);
+ esg_textual_decoder_namespace_prefix_list_for_each(textual_decoder_init, namespace_prefix) {
+ fprintf(stdout, " prefix_string_ptr %d\n", namespace_prefix->prefix_string_ptr);
+ fprintf(stdout, " namespace_URI_ptr %d\n\n", namespace_prefix->namespace_uri_ptr);
+ }
+ fprintf(stdout, " num_fragment_types %d\n\n", textual_decoder_init->num_fragment_types);
+ esg_textual_decoder_xml_fragment_type_list_for_each(textual_decoder_init, xml_fragment_type) {
+ fprintf(stdout, " xpath_ptr %d\n", xml_fragment_type->xpath_ptr);
+ fprintf(stdout, " ESG_XML_fragment_type %d\n\n", xml_fragment_type->xml_fragment_type);
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown EncodingVersion\n");
+ }
+ }
+
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_id\n");
+ }
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown structure_type\n");
+ }
+ }
+ }
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, "structure_body_ptr %d\n", container->structure_body_ptr);
+ fprintf(stdout, "structure_body_length %d\n\n", container->structure_body_length);
+
+ // ESG XML Fragment
+ if (fragment_management_information) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "ESG XML Fragment\n");
+ fprintf(stdout, "**************************************************\n\n");
+
+ struct esg_encapsulation_entry *entry;
+ esg_encapsulation_structure_entry_list_for_each(fragment_management_information, entry) {
+ switch (entry->fragment_reference->fragment_type) {
+ case 0x00: {
+ if (data_repository) {
+ struct esg_encapsulated_textual_esg_xml_fragment *esg_xml_fragment = esg_encapsulated_textual_esg_xml_fragment_decode(data_repository->data + entry->fragment_reference->data_repository_offset, data_repository->length);
+
+ fprintf(stdout, "ESG_XML_fragment_type %d\n", esg_xml_fragment->esg_xml_fragment_type);
+ fprintf(stdout, "data_length %d\n", esg_xml_fragment->data_length);
+ fprintf(stdout, "fragment_version %d\n", entry->fragment_version);
+ fprintf(stdout, "fragment_id %d\n\n", entry->fragment_id);
+ char *string = (char *) malloc(esg_xml_fragment->data_length + 1);
+ memcpy(string, esg_xml_fragment->data, esg_xml_fragment->data_length);
+ string[esg_xml_fragment->data_length] = 0;
+ fprintf(stdout, "%s\n", string);
+
+ } else {
+ fprintf(stderr, "ESG Data Repository not found");
+ }
+ break;
+ }
+ case 0x01: {
+ // TODO
+ break;
+ }
+ case 0x02: {
+ // TODO
+ break;
+ }
+ default: {
+ }
+ }
+ }
+ }
+
+ // String
+ if (init_message) {
+ fprintf(stdout, "**************************************************\n");
+ fprintf(stdout, "String\n");
+ fprintf(stdout, "**************************************************\n\n");
+
+ switch (init_message->encoding_version) {
+ case 0xF1: {
+ // TODO Bim
+ break;
+ }
+ case 0xF2: {
+ // TODO GZIP
+ break;
+ }
+ case 0xF3: {
+ // RAW
+ if (string_repository) {
+ textual_decoder_init = (struct esg_textual_decoder_init *) init_message->decoder_init;
+ esg_textual_decoder_namespace_prefix_list_for_each(textual_decoder_init, namespace_prefix) {
+ fprintf(stdout, "prefix_string_ptr %d\n", namespace_prefix->prefix_string_ptr);
+ fprintf(stdout, "%s\n", string_repository->data + namespace_prefix->prefix_string_ptr);
+ fprintf(stdout, "namespace_URI_ptr %d\n", namespace_prefix->namespace_uri_ptr);
+ fprintf(stdout, "%s\n\n", string_repository->data + namespace_prefix->namespace_uri_ptr - 1); // TODO -1
+ }
+
+ esg_textual_decoder_xml_fragment_type_list_for_each(textual_decoder_init, xml_fragment_type) {
+ fprintf(stdout, "xpath_ptr %d\n", xml_fragment_type->xpath_ptr);
+ fprintf(stdout, "ESG_XML_fragment_type %d\n", xml_fragment_type->xml_fragment_type);
+ fprintf(stdout, "%s\n\n", string_repository->data + xml_fragment_type->xpath_ptr - 1); // TODO -1
+ }
+ }
+ break;
+ }
+ default: {
+ fprintf(stdout, " Unknown EncodingVersion\n");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/test/libucsi/Makefile b/test/libucsi/Makefile
new file mode 100644
index 0000000..1a831d0
--- /dev/null
+++ b/test/libucsi/Makefile
@@ -0,0 +1,13 @@
+# Makefile for linuxtv.org dvb-apps/test/libucsi
+
+binaries = testucsi
+
+CPPFLAGS += -I../../lib
+LDLIBS += ../../lib/libdvbapi/libdvbapi.a ../../lib/libdvbcfg/libdvbcfg.a \
+ ../../lib/libdvbsec/libdvbsec.a ../../lib/libucsi/libucsi.a
+
+.PHONY: all
+
+all: $(binaries)
+
+include ../../Make.rules
diff --git a/test/libucsi/testucsi.c b/test/libucsi/testucsi.c
new file mode 100644
index 0000000..e0a16c1
--- /dev/null
+++ b/test/libucsi/testucsi.c
@@ -0,0 +1,3528 @@
+/*
+ * section and descriptor parser test/sample application.
+ *
+ * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <libucsi/mpeg/descriptor.h>
+#include <libucsi/mpeg/section.h>
+#include <libucsi/dvb/descriptor.h>
+#include <libucsi/dvb/section.h>
+#include <libucsi/atsc/descriptor.h>
+#include <libucsi/atsc/section.h>
+#include <libucsi/transport_packet.h>
+#include <libucsi/section_buf.h>
+#include <libucsi/dvb/types.h>
+#include <libdvbapi/dvbdemux.h>
+#include <libdvbapi/dvbfe.h>
+#include <libdvbcfg/dvbcfg_zapchannel.h>
+#include <libdvbsec/dvbsec_api.h>
+#include <libdvbsec/dvbsec_cfg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <fcntl.h>
+
+void receive_data(int dvrfd, int timeout, int data_type);
+void parse_section(uint8_t *buf, int len, int pid, int data_type);
+void parse_dvb_section(uint8_t *buf, int len, int pid, int data_type, struct section *section);
+void parse_atsc_section(uint8_t *buf, int len, int pid, int data_type, struct section *section);
+void parse_descriptor(struct descriptor *d, int indent, int data_type);
+void parse_dvb_descriptor(struct descriptor *d, int indent, int data_type);
+void parse_atsc_descriptor(struct descriptor *d, int indent, int data_type);
+void iprintf(int indent, char *fmt, ...);
+void hexdump(int indent, char *prefix, uint8_t *buf, int buflen);
+void atsctextdump(char *header, int indent, struct atsc_text *atext, int len);
+int channels_cb(struct dvbcfg_zapchannel *channel, void *private);
+void ts_from_file(char *filename, int data_type);
+
+#define TIME_CHECK_VAL 1131835761
+#define DURATION_CHECK_VAL 5643
+
+#define MAX_TUNE_TIME 3000
+#define MAX_DUMP_TIME 60
+
+#define DATA_TYPE_MPEG 0
+#define DATA_TYPE_DVB 1
+#define DATA_TYPE_ATSC 2
+
+
+struct dvbfe_handle *fe;
+struct dvbfe_info feinfo;
+int demuxfd;
+int dvrfd;
+
+int main(int argc, char *argv[])
+{
+ int adapter;
+ char *channelsfile;
+ int pidlimit = -1;
+ dvbdate_t dvbdate;
+ dvbduration_t dvbduration;
+
+ // process arguments
+ if ((argc < 3) || (argc > 4)) {
+ fprintf(stderr, "Syntax: testucsi <adapter id>|-atscfile <filename> <zapchannels file> [<pid to limit to>]\n");
+ exit(1);
+ }
+ if (!strcmp(argv[1], "-atscfile")) {
+ ts_from_file(argv[2], DATA_TYPE_ATSC);
+ exit(0);
+ }
+ adapter = atoi(argv[1]);
+ channelsfile = argv[2];
+ if (argc == 4)
+ sscanf(argv[3], "%i", &pidlimit);
+ printf("Using adapter %i\n", adapter);
+
+ // check the dvbdate conversion functions
+ unixtime_to_dvbdate(TIME_CHECK_VAL, dvbdate);
+ if (dvbdate_to_unixtime(dvbdate) != TIME_CHECK_VAL) {
+ fprintf(stderr, "XXXX dvbdate function check failed (%i!=%i)\n",
+ TIME_CHECK_VAL, (int) dvbdate_to_unixtime(dvbdate));
+ exit(1);
+ }
+ seconds_to_dvbduration(DURATION_CHECK_VAL, dvbduration);
+ if (dvbduration_to_seconds(dvbduration) != DURATION_CHECK_VAL) {
+ fprintf(stderr, "XXXX dvbduration function check failed (%i!=%i)\n",
+ DURATION_CHECK_VAL, (int) dvbduration_to_seconds(dvbduration));
+ exit(1);
+ }
+
+ // open the frontend
+ if ((fe = dvbfe_open(adapter, 0, 0)) == NULL) {
+ perror("open frontend");
+ exit(1);
+ }
+ dvbfe_get_info(fe, 0, &feinfo, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
+ int data_type = DATA_TYPE_MPEG;
+ switch(feinfo.type) {
+ case DVBFE_TYPE_DVBS:
+ case DVBFE_TYPE_DVBC:
+ case DVBFE_TYPE_DVBT:
+ data_type = DATA_TYPE_DVB;
+ break;
+
+ case DVBFE_TYPE_ATSC:
+ data_type = DATA_TYPE_ATSC;
+ break;
+ }
+
+ // open demux devices
+ if ((demuxfd = dvbdemux_open_demux(adapter, 0, 0)) < 0) {
+ perror("demux");
+ exit(1);
+ }
+ if ((dvrfd = dvbdemux_open_dvr(adapter, 0, 1, 1)) < 0) {
+ perror("dvr");
+ exit(1);
+ }
+
+ // make the demux buffer a bit larger
+ if (dvbdemux_set_buffer(demuxfd, 1024*1024)) {
+ perror("set buffer");
+ exit(1);
+ }
+
+ // setup filter to capture stuff
+ if (dvbdemux_set_pid_filter(demuxfd, pidlimit, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DVR, 1)) {
+ perror("set pid filter");
+ exit(1);
+ }
+
+ // process all the channels
+ FILE *channels = fopen(channelsfile, "r");
+ if (channels == NULL) {
+ fprintf(stderr, "Unable to open %s\n", channelsfile);
+ exit(1);
+ }
+ dvbcfg_zapchannel_parse(channels, channels_cb, (void*) (long) data_type);
+ return 0;
+}
+
+void ts_from_file(char *filename, int data_type) {
+ int fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open file %s\n", filename);
+ exit(1);
+ }
+ receive_data(fd, 1000000000, data_type);
+}
+
+int channels_cb(struct dvbcfg_zapchannel *channel, void *private)
+{
+ long data_type = (long) private;
+ struct dvbsec_config sec;
+
+ if (dvbsec_cfg_find(NULL, "UNIVERSAL", &sec)) {
+ fprintf(stderr, "Unable to find SEC id\n");
+ exit(1);
+ }
+
+ if (dvbsec_set(fe,
+ &sec,
+ channel->polarization,
+ DISEQC_SWITCH_UNCHANGED,
+ DISEQC_SWITCH_UNCHANGED,
+ &channel->fe_params,
+ MAX_TUNE_TIME)) {
+ fprintf(stderr, "Failed to lock!\n");
+ } else {
+ printf("Tuned successfully!\n");
+ receive_data(dvrfd, MAX_DUMP_TIME, data_type);
+ }
+
+ return 0;
+}
+
+void receive_data(int _dvrfd, int timeout, int data_type)
+{
+ unsigned char databuf[TRANSPORT_PACKET_LENGTH*20];
+ int sz;
+ int pid;
+ int i;
+ int used;
+ int section_status;
+ time_t starttime;
+ unsigned char continuities[TRANSPORT_MAX_PIDS];
+ struct section_buf *section_bufs[TRANSPORT_MAX_PIDS];
+ struct transport_packet *tspkt;
+ struct transport_values tsvals;
+
+ // process the data
+ starttime = time(NULL);
+ memset(continuities, 0, sizeof(continuities));
+ memset(section_bufs, 0, sizeof(section_bufs));
+ while((time(NULL) - starttime) < timeout) {
+ // got some!
+ if ((sz = read(_dvrfd, databuf, sizeof(databuf))) < 0) {
+ if (errno == EOVERFLOW) {
+ fprintf(stderr, "data overflow!\n");
+ continue;
+ } else if (errno == EAGAIN) {
+ usleep(100);
+ continue;
+ } else {
+ perror("read error");
+ exit(1);
+ }
+ }
+ for(i=0; i < sz; i+=TRANSPORT_PACKET_LENGTH) {
+ // parse the transport packet
+ tspkt = transport_packet_init(databuf + i);
+ if (tspkt == NULL) {
+ fprintf(stderr, "XXXX Bad sync byte\n");
+ continue;
+ }
+ pid = transport_packet_pid(tspkt);
+
+ // extract all TS packet values even though we don't need them (to check for
+ // library segfaults etc)
+ if (transport_packet_values_extract(tspkt, &tsvals, 0xffff) < 0) {
+ fprintf(stderr, "XXXX Bad packet received (pid:%04x)\n", pid);
+ continue;
+ }
+
+ // check continuity
+ if (transport_packet_continuity_check(tspkt,
+ tsvals.flags & transport_adaptation_flag_discontinuity,
+ continuities + pid)) {
+ fprintf(stderr, "XXXX Continuity error (pid:%04x)\n", pid);
+ continuities[pid] = 0;
+ if (section_bufs[pid] != NULL) {
+ section_buf_reset(section_bufs[pid]);
+ }
+ continue;
+ }
+
+ // allocate section buf if we don't have one already
+ if (section_bufs[pid] == NULL) {
+ section_bufs[pid] = (struct section_buf*)
+ malloc(sizeof(struct section_buf) + DVB_MAX_SECTION_BYTES);
+ if (section_bufs[pid] == NULL) {
+ fprintf(stderr, "Failed to allocate section buf (pid:%04x)\n", pid);
+ exit(1);
+ }
+ section_buf_init(section_bufs[pid], DVB_MAX_SECTION_BYTES);
+ }
+
+ // process the payload data as a section
+ while(tsvals.payload_length) {
+ used = section_buf_add_transport_payload(section_bufs[pid],
+ tsvals.payload,
+ tsvals.payload_length,
+ tspkt->payload_unit_start_indicator,
+ &section_status);
+ tspkt->payload_unit_start_indicator = 0;
+ tsvals.payload_length -= used;
+ tsvals.payload += used;
+
+ if (section_status == 1) {
+ parse_section(section_buf_data(section_bufs[pid]),
+ section_bufs[pid]->len, pid, data_type);
+ section_buf_reset(section_bufs[pid]);
+ } else if (section_status < 0) {
+ // some kind of error - just discard
+ fprintf(stderr, "XXXX bad section %04x %i\n",pid, section_status);
+ section_buf_reset(section_bufs[pid]);
+ }
+ }
+ }
+ }
+}
+
+void parse_section(uint8_t *buf, int len, int pid, int data_type)
+{
+ struct section *section;
+ struct section_ext *section_ext = NULL;
+
+ if ((section = section_codec(buf, len)) == NULL) {
+ return;
+ }
+
+ switch(section->table_id) {
+ case stag_mpeg_program_association:
+ {
+ struct mpeg_pat_section *pat;
+ struct mpeg_pat_program *cur;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode PAT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((pat = mpeg_pat_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX PAT section decode error\n");
+ return;
+ }
+ printf("SCT transport_stream_id:0x%04x\n", mpeg_pat_section_transport_stream_id(pat));
+ mpeg_pat_section_programs_for_each(pat, cur) {
+ printf("\tSCT program_number:0x%04x pid:0x%04x\n", cur->program_number, cur->pid);
+ }
+ break;
+ }
+
+ case stag_mpeg_conditional_access:
+ {
+ struct mpeg_cat_section *cat;
+ struct descriptor *curd;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode CAT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((cat = mpeg_cat_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX CAT section decode error\n");
+ return;
+ }
+ mpeg_cat_section_descriptors_for_each(cat, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_mpeg_program_map:
+ {
+ struct mpeg_pmt_section *pmt;
+ struct descriptor *curd;
+ struct mpeg_pmt_stream *cur_stream;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode PMT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((pmt = mpeg_pmt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX PMT section decode error\n");
+ return;
+ }
+ printf("SCT program_number:0x%04x pcr_pid:0x%02x\n", mpeg_pmt_section_program_number(pmt), pmt->pcr_pid);
+ mpeg_pmt_section_descriptors_for_each(pmt, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
+ printf("\tSCT stream_type:0x%02x pid:0x%04x\n", cur_stream->stream_type, cur_stream->pid);
+ mpeg_pmt_stream_descriptors_for_each(cur_stream, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_mpeg_transport_stream_description:
+ {
+ struct mpeg_tsdt_section *tsdt;
+ struct descriptor *curd;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode TSDT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tsdt = mpeg_tsdt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX TSDT section decode error\n");
+ return;
+ }
+ mpeg_tsdt_section_descriptors_for_each(tsdt, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_mpeg_metadata:
+ {
+ struct mpeg_metadata_section *metadata;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode metadata (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((metadata = mpeg_metadata_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX metadata section decode error\n");
+ return;
+ }
+ printf("SCT random_access_indicator:%i decoder_config_flag:%i fragment_indicator:%i service_id:%02x\n",
+ mpeg_metadata_section_random_access_indicator(metadata),
+ mpeg_metadata_section_decoder_config_flag(metadata),
+ mpeg_metadata_section_fragment_indicator(metadata),
+ mpeg_metadata_section_service_id(metadata));
+ hexdump(0, "SCT ", mpeg_metadata_section_data(metadata), mpeg_metadata_section_data_length(metadata));
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_mpeg_iso14496_scene_description:
+ case stag_mpeg_iso14496_object_description:
+ {
+ struct mpeg_odsmt_section *odsmt;
+ struct mpeg_odsmt_stream *cur_stream;
+ struct descriptor *curd;
+ int _index;
+ uint8_t *objects;
+ size_t objects_length;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode ISO14496 (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((odsmt = mpeg_odsmt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX ISO14496 section decode error\n");
+ return;
+ }
+ printf("SCT PID:0x%04x\n", mpeg_odsmt_section_pid(odsmt));
+ mpeg_odsmt_section_streams_for_each(osdmt, cur_stream, _index) {
+ if (odsmt->stream_count == 0) {
+ printf("\tSCT SINGLE 0x%04x\n", cur_stream->u.single.esid);
+ } else {
+ printf("\tSCT MULTI 0x%04x 0x%02x\n", cur_stream->u.multi.esid, cur_stream->u.multi.fmc);
+ }
+ mpeg_odsmt_stream_descriptors_for_each(osdmt, cur_stream, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ objects = mpeg_odsmt_section_object_descriptors(odsmt, &objects_length);
+ if (objects == NULL) {
+ printf("SCT XXXX OSDMT parse error\n");
+ break;
+ }
+ hexdump(1, "SCT ", objects, objects_length);
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ default:
+ switch(data_type) {
+ case DATA_TYPE_DVB:
+ parse_dvb_section(buf, len, pid, data_type, section);
+ break;
+
+ case DATA_TYPE_ATSC:
+ parse_atsc_section(buf, len, pid, data_type, section);
+ break;
+
+ default:
+ fprintf(stderr, "SCT XXXX Unknown table_id:0x%02x (pid:0x%04x)\n",
+ section->table_id, pid);
+// hexdump(0, "SCT ", buf, len);
+ return;
+ }
+ }
+
+ printf("\n");
+}
+
+void parse_dvb_section(uint8_t *buf, int len, int pid, int data_type, struct section *section)
+{
+ struct section_ext *section_ext = NULL;
+
+ switch(section->table_id) {
+ case stag_dvb_network_information_actual:
+ case stag_dvb_network_information_other:
+ {
+ struct dvb_nit_section *nit;
+ struct descriptor *curd;
+ struct dvb_nit_section_part2 *part2;
+ struct dvb_nit_transport *cur_transport;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode NIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((nit = dvb_nit_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX NIT section decode error\n");
+ return;
+ }
+ printf("SCT network_id:0x%04x\n", dvb_nit_section_network_id(nit));
+ dvb_nit_section_descriptors_for_each(nit, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ part2 = dvb_nit_section_part2(nit);
+ dvb_nit_section_transports_for_each(nit, part2, cur_transport) {
+ printf("\tSCT transport_stream_id:0x%04x original_network_id:0x%04x\n", cur_transport->transport_stream_id, cur_transport->original_network_id);
+ dvb_nit_transport_descriptors_for_each(cur_transport, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_service_description_actual:
+ case stag_dvb_service_description_other:
+ {
+ struct dvb_sdt_section *sdt;
+ struct dvb_sdt_service *cur_service;
+ struct descriptor *curd;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode SDT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((sdt = dvb_sdt_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX SDT section decode error\n");
+ return;
+ }
+ printf("SCT transport_stream_id:0x%04x original_network_id:0x%04x\n", dvb_sdt_section_transport_stream_id(sdt), sdt->original_network_id);
+ dvb_sdt_section_services_for_each(sdt, cur_service) {
+ printf("\tSCT service_id:0x%04x eit_schedule_flag:%i eit_present_following_flag:%i running_status:%i free_ca_mode:%i\n",
+ cur_service->service_id,
+ cur_service->eit_schedule_flag,
+ cur_service->eit_present_following_flag,
+ cur_service->running_status,
+ cur_service->free_ca_mode);
+ dvb_sdt_service_descriptors_for_each(cur_service, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_bouquet_association:
+ {
+ struct dvb_bat_section *bat;
+ struct descriptor *curd;
+ struct dvb_bat_section_part2 *part2;
+ struct dvb_bat_transport *cur_transport;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode BAT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((bat = dvb_bat_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX BAT section decode error\n");
+ return;
+ }
+ printf("SCT bouquet_id:0x%04x\n", dvb_bat_section_bouquet_id(bat));
+ dvb_bat_section_descriptors_for_each(bat, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ part2 = dvb_bat_section_part2(bat);
+ dvb_bat_section_transports_for_each(part2, cur_transport) {
+ printf("\tSCT transport_stream_id:0x%04x original_network_id:0x%04x\n",
+ cur_transport->transport_stream_id,
+ cur_transport->original_network_id);
+ dvb_bat_transport_descriptors_for_each(cur_transport, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_update_notification:
+ case stag_dvb_ip_mac_notification:
+ {
+ struct dvb_int_section *_int;
+ struct descriptor *curd;
+ struct dvb_int_target *cur_target;
+ struct dvb_int_operational_loop *operational_loop;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode INT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((_int = dvb_int_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX INT section decode error\n");
+ return;
+ }
+ printf("SCT action_type:0x%02x platform_id_hash:0x%02x platform_id:0x%06x processing_order:0x%02x\n",
+ dvb_int_section_action_type(_int),
+ dvb_int_section_platform_id_hash(_int),
+ _int->platform_id,
+ _int->processing_order);
+ dvb_int_section_platform_descriptors_for_each(_int, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ dvb_int_section_target_loop_for_each(_int, cur_target) {
+ dvb_int_target_target_descriptors_for_each(cur_target, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ operational_loop = dvb_int_target_operational_loop(cur_target);
+ dvb_int_operational_loop_operational_descriptors_for_each(operational_loop, curd) {
+ parse_descriptor(curd, 3, data_type);
+ }
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_dvb_event_information_nownext_actual:
+ case stag_dvb_event_information_nownext_other:
+ case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+ case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
+ {
+ struct dvb_eit_section *eit;
+ struct dvb_eit_event *cur_event;
+ struct descriptor *curd;
+ time_t start_time;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode EIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((eit = dvb_eit_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "XXXX EIT section decode error\n");
+ return;
+ }
+ printf("SCT service_id:0x%04x transport_stream_id:0x%04x original_network_id:0x%04x segment_last_section_number:0x%02x last_table_id:0x%02x\n",
+ dvb_eit_section_service_id(eit),
+ eit->transport_stream_id,
+ eit->original_network_id,
+ eit->segment_last_section_number,
+ eit->last_table_id);
+ dvb_eit_section_events_for_each(eit, cur_event) {
+ start_time = dvbdate_to_unixtime(cur_event->start_time);
+ printf("\tSCT event_id:0x%04x duration:%i running_status:%i free_ca_mode:%i start_time:%i -- %s",
+ cur_event->event_id,
+ dvbduration_to_seconds(cur_event->duration),
+ cur_event->running_status,
+ cur_event->free_ca_mode,
+ (int) start_time,
+ ctime(&start_time));
+ dvb_eit_event_descriptors_for_each(cur_event, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_dvb_time_date:
+ {
+ struct dvb_tdt_section *tdt;
+ time_t dvbtime;
+
+ printf("SCT Decode TDT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tdt = dvb_tdt_section_codec(section)) == NULL) {
+ fprintf(stderr, "XXXX TDT section decode error\n");
+ return;
+ }
+ dvbtime = dvbdate_to_unixtime(tdt->utc_time);
+ printf("SCT Time: %i -- %s", (int) dvbtime, ctime(&dvbtime));
+ break;
+ }
+
+ case stag_dvb_running_status:
+ {
+ struct dvb_rst_section *rst;
+ struct dvb_rst_status *cur_status;
+
+ printf("SCT Decode RST (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((rst = dvb_rst_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX RST section decode error\n");
+ return;
+ }
+ dvb_rst_section_statuses_for_each(rst, cur_status) {
+ printf("\tSCT transport_stream_id:0x%04x original_network_id:0x%04x service_id:0x%04x event_id:0x%04x running_status:%i\n",
+ cur_status->transport_stream_id,
+ cur_status->original_network_id,
+ cur_status->service_id,
+ cur_status->event_id,
+ cur_status->running_status);
+ }
+
+// hexdump(0, "SCT ", buf, len);
+// getchar();
+ break;
+ }
+
+ case stag_dvb_stuffing:
+ {
+ struct dvb_st_section *st;
+
+ printf("SCT Decode ST (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((st = dvb_st_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX ST section decode error\n");
+ return;
+ }
+ printf("SCT Length: %i\n", dvb_st_section_data_length(st));
+ break;
+ }
+
+ case stag_dvb_time_offset:
+ {
+ struct dvb_tot_section *tot;
+ struct descriptor *curd;
+ time_t dvbtime;
+
+ if (section_check_crc(section))
+ return;
+ printf("SCT Decode TOT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tot = dvb_tot_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX TOT section decode error\n");
+ return;
+ }
+ dvbtime = dvbdate_to_unixtime(tot->utc_time);
+ printf("SCT utc_time: %i -- %s", (int) dvbtime, ctime(&dvbtime));
+ dvb_tot_section_descriptors_for_each(tot, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_dvb_tva_container:
+ {
+ struct dvb_tva_container_section *tva;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode tva (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tva = dvb_tva_container_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX tva section decode error\n");
+ return;
+ }
+ printf("SCT container_id:%04x\n",
+ dvb_tva_container_section_container_id(tva));
+ hexdump(0, "SCT ", dvb_tva_container_section_data(tva), dvb_tva_container_section_data_length(tva));
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_dvb_discontinuity_information:
+ {
+ struct dvb_dit_section *dit;
+
+ printf("SCT Decode DIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((dit = dvb_dit_section_codec(section)) == NULL) {
+ fprintf(stderr, "SCT XXXX DIT section decode error\n");
+ return;
+ }
+ printf("SCT transition_flag:%i\n", dit->transition_flag);
+
+// hexdump(0, "SCT ", buf, len);
+// getchar();
+ break;
+ }
+
+ case stag_dvb_selection_information:
+ {
+ struct dvb_sit_section *sit;
+ struct descriptor *curd;
+ struct dvb_sit_service *cur_service;
+
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ printf("SCT Decode SIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((sit = dvb_sit_section_codec(section_ext)) == NULL) {
+ fprintf(stderr, "SCT XXXX SIT section decode error\n");
+ return;
+ }
+ dvb_sit_section_descriptors_for_each(sit, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ dvb_sit_section_services_for_each(sit, cur_service) {
+ printf("\tSCT service_id:0x%04x running_status:%i\n", cur_service->service_id, cur_service->running_status);
+ dvb_sit_service_descriptors_for_each(cur_service, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ default:
+ fprintf(stderr, "SCT XXXX Unknown table_id:0x%02x (pid:0x%04x)\n", section->table_id, pid);
+// hexdump(0, "SCT ", buf, len);
+ return;
+ }
+}
+
+void parse_atsc_section(uint8_t *buf, int len, int pid, int data_type, struct section *section)
+{
+ struct section_ext *section_ext = NULL;
+ struct atsc_section_psip *section_psip = NULL;
+ if ((section_ext = section_ext_decode(section, 1)) == NULL) {
+ return;
+ }
+ if ((section_psip = atsc_section_psip_decode(section_ext)) == NULL) {
+ return;
+ }
+
+ printf("SCT protocol_version:%i\n", section_psip->protocol_version);
+
+ switch(section->table_id) {
+ case stag_atsc_master_guide:
+ {
+ struct atsc_mgt_section *mgt;
+ struct atsc_mgt_table *cur_table;
+ struct atsc_mgt_section_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode MGT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((mgt = atsc_mgt_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX MGT section decode error\n");
+ return;
+ }
+ atsc_mgt_section_tables_for_each(mgt, cur_table, idx) {
+ printf("\tSCT table_type:0x%04x table_type_PID:%04x table_type_version_number:%i number_bytes:%i\n",
+ cur_table->table_type,
+ cur_table->table_type_PID,
+ cur_table->table_type_version_number,
+ cur_table->number_bytes);
+ atsc_mgt_table_descriptors_for_each(cur_table, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ part2 = atsc_mgt_section_part2(mgt);
+ atsc_mgt_section_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_atsc_terrestrial_virtual_channel:
+ {
+ struct atsc_tvct_section *tvct;
+ struct atsc_tvct_channel *cur_channel;
+ struct atsc_tvct_section_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode TVCT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((tvct = atsc_tvct_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX TVCT section decode error\n");
+ return;
+ }
+ printf("\tSCT tranport_stream_id:0x%04x\n",
+ atsc_tvct_section_transport_stream_id(tvct));
+
+ atsc_tvct_section_channels_for_each(tvct, cur_channel, idx) {
+ hexdump(0, "SCT short_name ", (uint8_t*) cur_channel->short_name, 7*2);
+
+ printf("\tSCT major_channel_number:%04x minor_channel_number:%04x modulation_mode:%02x carrier_frequency:%i channel_TSID:%04x program_number:%04x ETM_location:%i access_controlled:%i hidden:%i hide_guide:%i service_type:%02x source_id:%04x\n",
+ cur_channel->major_channel_number,
+ cur_channel->minor_channel_number,
+ cur_channel->modulation_mode,
+ cur_channel->carrier_frequency,
+ cur_channel->channel_TSID,
+ cur_channel->program_number,
+ cur_channel->ETM_location,
+ cur_channel->access_controlled,
+ cur_channel->hidden,
+ cur_channel->hide_guide,
+ cur_channel->service_type,
+ cur_channel->source_id);
+ atsc_tvct_channel_descriptors_for_each(cur_channel, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ part2 = atsc_tvct_section_part2(tvct);
+ atsc_tvct_section_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_atsc_cable_virtual_channel:
+ {
+ struct atsc_cvct_section *cvct;
+ struct atsc_cvct_channel *cur_channel;
+ struct atsc_cvct_section_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode CVCT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((cvct = atsc_cvct_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX CVCT section decode error\n");
+ return;
+ }
+ printf("\tSCT tranport_stream_id:0x%04x\n",
+ atsc_cvct_section_transport_stream_id(cvct));
+
+ atsc_cvct_section_channels_for_each(cvct, cur_channel, idx) {
+ hexdump(0, "SCT short_name ", (uint8_t*) cur_channel->short_name, 7*2);
+
+ printf("\tSCT major_channel_number:%04x minor_channel_number:%04x modulation_mode:%02x carrier_frequency:%i channel_TSID:%04x program_number:%04x ETM_location:%i access_controlled:%i hidden:%i path_select:%i out_of_band:%i hide_guide:%i service_type:%02x source_id:%04x\n",
+ cur_channel->major_channel_number,
+ cur_channel->minor_channel_number,
+ cur_channel->modulation_mode,
+ cur_channel->carrier_frequency,
+ cur_channel->channel_TSID,
+ cur_channel->program_number,
+ cur_channel->ETM_location,
+ cur_channel->access_controlled,
+ cur_channel->hidden,
+ cur_channel->path_select,
+ cur_channel->out_of_band,
+ cur_channel->hide_guide,
+ cur_channel->service_type,
+ cur_channel->source_id);
+ atsc_cvct_channel_descriptors_for_each(cur_channel, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+
+ part2 = atsc_cvct_section_part2(cvct);
+ atsc_cvct_section_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+ break;
+ }
+
+ case stag_atsc_rating_region:
+ {
+ struct atsc_rrt_section *rrt;
+ struct atsc_rrt_section_part2 *part2;
+ struct atsc_rrt_dimension *cur_dimension;
+ struct atsc_rrt_dimension_part2 *dpart2;
+ struct atsc_rrt_dimension_value *cur_value;
+ struct atsc_rrt_dimension_value_part2 *vpart2;
+ struct atsc_rrt_section_part3 *part3;
+ struct descriptor *curd;
+ int didx;
+ int vidx;
+
+ printf("SCT Decode RRT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((rrt = atsc_rrt_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX RRT section decode error\n");
+ return;
+ }
+ printf("\tSCT rating_region:0x%02x\n",
+ atsc_rrt_section_rating_region(rrt));
+ atsctextdump("SCT region_name:", 1,
+ atsc_rrt_section_rating_region_name_text(rrt),
+ rrt->rating_region_name_length);
+
+ part2 = atsc_rrt_section_part2(rrt);
+ atsc_rrt_section_dimensions_for_each(part2, cur_dimension, didx) {
+ atsctextdump("SCT dimension_name:", 2,
+ atsc_rrt_dimension_name_text(cur_dimension),
+ cur_dimension->dimension_name_length);
+
+ dpart2 = atsc_rrt_dimension_part2(cur_dimension);
+ printf("\tSCT graduated_scale:%i\n",
+ dpart2->graduated_scale);
+
+ atsc_rrt_dimension_part2_values_for_each(dpart2, cur_value, vidx) {
+ atsctextdump("SCT value_abbrev_name:", 3,
+ atsc_rrt_dimension_value_abbrev_rating_value_text(cur_value),
+ cur_value->abbrev_rating_value_length);
+
+ vpart2 = atsc_rrt_dimension_value_part2(cur_value);
+ atsctextdump("SCT value_text:", 3,
+ atsc_rrt_dimension_value_part2_rating_value_text(vpart2),
+ vpart2->rating_value_length);
+ }
+ }
+
+ part3 = atsc_rrt_section_part3(part2);
+ atsc_rrt_section_part3_descriptors_for_each(part3, curd) {
+ parse_descriptor(curd, 1, data_type);
+ }
+
+ hexdump(0, "SCT ", buf, len);
+ getchar();
+ break;
+ }
+
+ case stag_atsc_event_information:
+ {
+ struct atsc_eit_section *eit;
+ struct atsc_eit_event *cur_event;
+ struct atsc_eit_event_part2 *part2;
+ struct descriptor *curd;
+ int idx;
+
+ printf("SCT Decode EIT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((eit = atsc_eit_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX EIT section decode error\n");
+ return;
+ }
+ printf("\tSCT source_id:0x%04x\n",
+ atsc_eit_section_source_id(eit));
+
+ atsc_eit_section_events_for_each(eit, cur_event, idx) {
+ printf("\t\tSCT event_id:%04x start_time:%i ETM_location:%i length_in_secs:%i\n",
+ cur_event->event_id,
+ cur_event->start_time,
+ cur_event->ETM_location,
+ cur_event->length_in_seconds);
+
+ atsctextdump("SCT title:", 2,
+ atsc_eit_event_name_title_text(cur_event),
+ cur_event->title_length);
+
+ part2 = atsc_eit_event_part2(cur_event);
+
+ atsc_eit_event_part2_descriptors_for_each(part2, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ }
+ break;
+ }
+
+ case stag_atsc_extended_text:
+ {
+ struct atsc_ett_section *ett;
+
+ printf("SCT Decode ETT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((ett = atsc_ett_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX ETT section decode error\n");
+ return;
+ }
+ printf("\tSCT ETM_source_id:0x%04x ETM_sub_id:%04x ETM_type:%02x\n",
+ ett->ETM_source_id,
+ ett->ETM_sub_id,
+ ett->ETM_type);
+ atsctextdump("SCT text:", 1,
+ atsc_ett_section_extended_text_message(ett),
+ atsc_ett_section_extended_text_message_length(ett));
+ break;
+ }
+
+ case stag_atsc_system_time:
+ {
+ struct atsc_stt_section *stt;
+ struct descriptor *curd;
+
+ printf("SCT Decode STT (pid:0x%04x) (table:0x%02x)\n", pid, section->table_id);
+ if ((stt = atsc_stt_section_codec(section_psip)) == NULL) {
+ fprintf(stderr, "SCT XXXX STT section decode error\n");
+ return;
+ }
+ printf("\tSCT system_time:%i gps_utc_offset:%i DS_status:%i DS_day_of_month:%i DS_hour:%i\n",
+ stt->system_time,
+ stt->gps_utc_offset,
+ stt->DS_status,
+ stt->DS_day_of_month,
+ stt->DS_hour);
+ atsc_stt_section_descriptors_for_each(stt, curd) {
+ parse_descriptor(curd, 2, data_type);
+ }
+ break;
+ }
+
+ default:
+ fprintf(stderr, "SCT XXXX Unknown table_id:0x%02x (pid:0x%04x)\n", section->table_id, pid);
+ hexdump(0, "SCT ", buf, len);
+ return;
+ }
+}
+
+void parse_descriptor(struct descriptor *d, int indent, int data_type)
+{
+ switch(d->tag) {
+ case dtag_mpeg_video_stream:
+ {
+ struct mpeg_video_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_video_stream_descriptor\n");
+ dx = mpeg_video_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_video_stream_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC multiple_frame_rate_flag:%i frame_rate_code:%i mpeg_1_only_flag:%i constrained_parameter_flag:%i still_picture_flag:%i\n",
+ dx->multiple_frame_rate_flag,
+ dx->frame_rate_code,
+ dx->mpeg_1_only_flag,
+ dx->constrained_parameter_flag,
+ dx->still_picture_flag);
+ if (!dx->mpeg_1_only_flag) {
+ struct mpeg_video_stream_extra *extra = mpeg_video_stream_descriptor_extra(dx);
+ iprintf(indent, "DSC profile_and_level_indication:0x%02x chroma_format:%i frame_rate_extension:%i\n",
+ extra->profile_and_level_indication,
+ extra->chroma_format,
+ extra->frame_rate_extension);
+ }
+ break;
+ }
+
+ case dtag_mpeg_audio_stream:
+ {
+ struct mpeg_audio_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_audio_stream_descriptor\n");
+ dx = mpeg_audio_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_audio_stream_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC free_format_flag:%i id:%i layer:%i variable_rate_audio_indicator:%i\n",
+ dx->free_format_flag,
+ dx->id,
+ dx->layer,
+ dx->variable_rate_audio_indicator);
+ break;
+ }
+
+ case dtag_mpeg_hierarchy:
+ {
+ struct mpeg_hierarchy_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_hierarchy_descriptor\n");
+ dx = mpeg_hierarchy_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_hierarchy_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC hierarchy_type:%i hierarchy_layer_index:%i hierarchy_embedded_layer_index:%i hierarchy_channel:%i\n",
+ dx->hierarchy_type,
+ dx->hierarchy_layer_index,
+ dx->hierarchy_embedded_layer_index,
+ dx->hierarchy_channel);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_registration:
+ {
+ struct mpeg_registration_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_registration_descriptor\n");
+ dx = mpeg_registration_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_registration_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC format_identifier:0x%x\n",
+ dx->format_identifier);
+ iprintf(indent, "DSC additional_id_info:\n");
+ hexdump(indent, "DSC ",
+ mpeg_registration_descriptor_additional_id_info(dx),
+ mpeg_registration_descriptor_additional_id_info_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_data_stream_alignment:
+ {
+ struct mpeg_data_stream_alignment_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_data_stream_alignment_descriptor\n");
+ dx = mpeg_data_stream_alignment_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_data_stream_alignment_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC alignment_type:%i\n",
+ dx->alignment_type);
+ break;
+ }
+
+ case dtag_mpeg_target_background_grid:
+ {
+ struct mpeg_target_background_grid_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_target_background_grid_descriptor\n");
+ dx = mpeg_target_background_grid_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_target_background_grid_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC horizontal_size:%i vertical_size:%i aspect_ratio_information:%i\n",
+ dx->horizontal_size,
+ dx->vertical_size,
+ dx->aspect_ratio_information);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_video_window:
+ {
+ struct mpeg_video_window_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_video_window_descriptor\n");
+ dx = mpeg_video_window_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_video_window_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC horizontal_offset:%i vertical_offset:%i window_priority:%i\n",
+ dx->horizontal_offset,
+ dx->vertical_offset,
+ dx->window_priority);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_ca:
+ {
+ struct mpeg_ca_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_ca_descriptor\n");
+ dx = mpeg_ca_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_ca_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC ca_system_id:0x%04x ca_pid:0x%04x\n",
+ dx->ca_system_id,
+ dx->ca_pid);
+ iprintf(indent, "DSC data:\n");
+ hexdump(indent, "DSC ", mpeg_ca_descriptor_data(dx), mpeg_ca_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_iso_639_language:
+ {
+ struct mpeg_iso_639_language_descriptor *dx;
+ struct mpeg_iso_639_language_code *cur_lang;
+
+ iprintf(indent, "DSC Decode mpeg_iso_639_language_descriptor\n");
+ dx = mpeg_iso_639_language_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_iso_639_language_descriptor decode error\n");
+ return;
+ }
+ mpeg_iso_639_language_descriptor_languages_for_each(dx, cur_lang) {
+ iprintf(indent+1, "DSC language_code:%.3s audio_type:0x%02x\n",
+ cur_lang->language_code,
+ cur_lang->audio_type);
+ }
+ break;
+ }
+
+ case dtag_mpeg_system_clock:
+ {
+ struct mpeg_system_clock_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_system_clock_descriptor\n");
+ dx = mpeg_system_clock_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_system_clock_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC external_clock_reference_indicator:%i clock_accuracy_integer:%i clock_accuracy_exponent:%i\n",
+ dx->external_clock_reference_indicator,
+ dx->clock_accuracy_integer,
+ dx->clock_accuracy_exponent);
+ break;
+ }
+
+ case dtag_mpeg_multiplex_buffer_utilization:
+ {
+ struct mpeg_multiplex_buffer_utilization_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_multiplex_buffer_utilization_descriptor\n");
+ dx = mpeg_multiplex_buffer_utilization_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_multiplex_buffer_utilization_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC bound_valid_flag:%i ltw_offset_lower_bound:%i ltw_offset_upper_bound:%i\n",
+ dx->bound_valid_flag,
+ dx->ltw_offset_lower_bound,
+ dx->ltw_offset_upper_bound);
+ break;
+ }
+
+ case dtag_mpeg_copyright:
+ {
+ struct mpeg_copyright_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_copyright_descriptor\n");
+ dx = mpeg_copyright_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_copyright_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC copyright_identifier:0x%08x\n",
+ dx->copyright_identifier);
+ iprintf(indent, "DSC data:\n");
+ hexdump(indent, "DSC ", mpeg_copyright_descriptor_data(dx), mpeg_copyright_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_maximum_bitrate:
+ {
+ struct mpeg_maximum_bitrate_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_maximum_bitrate_descriptor\n");
+ dx = mpeg_maximum_bitrate_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_maximum_bitrate_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC maximum_bitrate:%i\n",
+ dx->maximum_bitrate);
+ break;
+ }
+
+ case dtag_mpeg_private_data_indicator:
+ {
+ struct mpeg_private_data_indicator_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_private_data_indicator_descriptor\n");
+ dx = mpeg_private_data_indicator_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_private_data_indicator_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC private_data_indicator:0x%x\n",
+ dx->private_data_indicator);
+ break;
+ }
+
+ case dtag_mpeg_smoothing_buffer:
+ {
+ struct mpeg_smoothing_buffer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_smoothing_buffer_descriptor\n");
+ dx = mpeg_smoothing_buffer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_smoothing_buffer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC sb_leak_rate:%i sb_size:%i\n",
+ dx->sb_leak_rate,
+ dx->sb_size);
+ break;
+ }
+
+ case dtag_mpeg_std:
+ {
+ struct mpeg_std_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_std_descriptor\n");
+ dx = mpeg_std_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_std_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC leak_valid_flag:%i\n",
+ dx->leak_valid_flag);
+ break;
+ }
+
+ case dtag_mpeg_ibp:
+ {
+ struct mpeg_ibp_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_ibp_descriptor\n");
+ dx = mpeg_ibp_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_ibp_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC closed_gop_flag:%i identical_gop_flag:%i max_gop_length:%i\n",
+ dx->closed_gop_flag, dx->identical_gop_flag, dx->max_gop_length);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_4_video:
+ {
+ struct mpeg4_video_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg4_video_descriptor\n");
+ dx = mpeg4_video_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg4_video_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mpeg4_visual_profile_and_level:0x%02x\n",
+ dx->mpeg4_visual_profile_and_level);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_4_audio:
+ {
+ struct mpeg4_audio_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg4_audio_descriptor\n");
+ dx = mpeg4_audio_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg4_audio_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mpeg4_audio_profile_and_level:0x%02x\n",
+ dx->mpeg4_audio_profile_and_level);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_iod:
+ {
+ struct mpeg_iod_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_iod_descriptor\n");
+ dx = mpeg_iod_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_iod_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC scope_of_iod_label:0x%08x iod_label:0x%02x\n",
+ dx->scope_of_iod_label, dx->iod_label);
+ iprintf(indent, "DSC iod:\n");
+ hexdump(indent, "DSC ", mpeg_iod_descriptor_iod(dx), mpeg_iod_descriptor_iod_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_sl:
+ {
+ struct mpeg_sl_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_sl_descriptor\n");
+ dx = mpeg_sl_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_sl_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC es_id:0x%04x\n",
+ dx->es_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_fmc:
+ {
+ struct mpeg_fmc_descriptor *dx;
+ struct mpeg_flex_mux *cur_fm;
+
+ iprintf(indent, "DSC Decode mpeg_fmc_descriptor\n");
+ dx = mpeg_fmc_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_fmc_descriptor_descriptor decode error\n");
+ return;
+ }
+ mpeg_fmc_descriptor_muxes_for_each(dx, cur_fm) {
+ iprintf(indent+1, "DSC es_id:0x%04x flex_mux_channel:0x%02x\n",
+ cur_fm->es_id,
+ cur_fm->flex_mux_channel);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_external_es_id:
+ {
+ struct mpeg_external_es_id_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_external_es_id_descriptor\n");
+ dx = mpeg_external_es_id_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_external_es_id_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC external_es_id:0x%04x\n",
+ dx->external_es_id);
+ break;
+ }
+
+ case dtag_mpeg_muxcode:
+ {
+ struct mpeg_muxcode_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_muxcode_descriptor\n");
+ dx = mpeg_muxcode_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_muxcode_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC entries:\n");
+ hexdump(indent, "DSC ", mpeg_muxcode_descriptor_entries(dx), mpeg_muxcode_descriptor_entries_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_fmxbuffer_size:
+ {
+ struct mpeg_fmxbuffer_size_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_fmxbuffer_size_descriptor\n");
+ dx = mpeg_fmxbuffer_size_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_fmxbuffer_size_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC descriptors:\n");
+ hexdump(indent, "DSC ", mpeg_fmxbuffer_size_descriptor_descriptors(dx), mpeg_fmxbuffer_size_descriptor_descriptors_length(dx));
+ break;
+ }
+
+ case dtag_mpeg_multiplex_buffer:
+ {
+ struct mpeg_multiplex_buffer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_multiplex_buffer_descriptor\n");
+ dx = mpeg_multiplex_buffer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_multiplex_buffer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mb_buffer_size:%i tb_leak_rate:%i\n",
+ dx->mb_buffer_size, dx->tb_leak_rate);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_content_labelling:
+ {
+ struct mpeg_content_labelling_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_content_labelling_descriptor\n");
+ dx = mpeg_content_labelling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_content_labelling_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_application_format:%04x\n",
+ dx->metadata_application_format);
+ struct mpeg_content_labelling_descriptor_application_format_identifier *id =
+ mpeg_content_labelling_descriptor_id(dx);
+ if (id != NULL) {
+ iprintf(indent, "DSC application_format_id:%04x\n",
+ id->id);
+ }
+ struct mpeg_content_labelling_descriptor_flags *flags =
+ mpeg_content_labelling_descriptor_flags(dx);
+ if (flags != NULL) {
+ iprintf(indent, "DSC content_reference_id_record_flag:%i content_time_base_indicator:%02x\n",
+ flags->content_reference_id_record_flag,
+ flags->content_time_base_indicator);
+
+ struct mpeg_content_labelling_descriptor_reference_id *reference_id =
+ mpeg_content_labelling_descriptor_reference_id(flags);
+ if (reference_id != NULL) {
+ hexdump(indent, "DSC reference_id " ,
+ mpeg_content_reference_id_data(reference_id),
+ reference_id->content_reference_id_record_length);
+ }
+
+ struct mpeg_content_labelling_descriptor_time_base *time_base =
+ mpeg_content_labelling_descriptor_time_base(flags);
+ if (time_base != NULL) {
+ iprintf(indent, "DSC time_base content_time_base_value:%lli metadata_time_base_value:%lli\n",
+ time_base->content_time_base_value,
+ time_base->metadata_time_base_value);
+ }
+
+ struct mpeg_content_labelling_descriptor_content_id *content_id =
+ mpeg_content_labelling_descriptor_content_id(flags);
+ if (content_id != NULL) {
+ iprintf(indent, "DSC content_id contentId:%i\n",
+ content_id->contentId);
+ }
+
+ struct mpeg_content_labelling_descriptor_time_base_association *time_base_assoc =
+ mpeg_content_labelling_descriptor_time_base_assoc(flags);
+ if (time_base_assoc != NULL) {
+ hexdump(indent, "DSC time_base_assoc" ,
+ mpeg_time_base_association_data(time_base_assoc),
+ time_base_assoc->time_base_association_data_length);
+ }
+
+ uint8_t *priv;
+ int priv_length;
+ priv = mpeg_content_labelling_descriptor_data(dx, flags, &priv_length);
+ hexdump(indent, "DSC private_data", priv, priv_length);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_metadata_pointer:
+ {
+ struct mpeg_metadata_pointer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_metadata_pointer_descriptor\n");
+ dx = mpeg_metadata_pointer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_metadata_pointer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_application_format:%04x\n",
+ dx->metadata_application_format);
+
+ struct mpeg_metadata_pointer_descriptor_application_format_identifier *id =
+ mpeg_metadata_pointer_descriptor_appid(dx);
+ if (id != NULL) {
+ iprintf(indent, "DSC application_format_id:%04x\n",
+ id->id);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_format_identifier *did =
+ mpeg_metadata_pointer_descriptor_formid(dx);
+ if (did != NULL) {
+ iprintf(indent, "DSC mpeg_metadata_pointer_descriptor_format_id:%04x\n",
+ did->id);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_flags *flags =
+ mpeg_metadata_pointer_descriptor_flags(dx);
+ if (flags != NULL) {
+ iprintf(indent, "DSC metadata_service_id:%i metadata_locator_record_flag:%i mpeg_carriage_flags:%x\n",
+ flags->metadata_service_id,
+ flags->metadata_locator_record_flag,
+ flags->mpeg_carriage_flags);
+
+ struct mpeg_metadata_pointer_descriptor_locator *locator =
+ mpeg_metadata_pointer_descriptor_locator(flags);
+ if (locator != NULL) {
+ hexdump(indent, "DSC locator" ,
+ mpeg_metadata_pointer_descriptor_locator_data(locator),
+ locator->metadata_locator_record_length);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_program_number *pnum=
+ mpeg_metadata_pointer_descriptor_program_number(flags);
+ if (pnum != NULL) {
+ iprintf(indent, "DSC program_number number:%04x\n",
+ pnum->number);
+ }
+
+ struct mpeg_metadata_pointer_descriptor_carriage *carriage =
+ mpeg_metadata_pointer_descriptor_carriage(flags);
+ if (carriage != NULL) {
+ iprintf(indent, "DSC carriage transport_stream_location:%04x transport_stream_id:%04x\n",
+ carriage->transport_stream_location,
+ carriage->transport_stream_id);
+ }
+
+ uint8_t *priv;
+ int priv_length;
+ priv = mpeg_metadata_pointer_descriptor_private_data(dx, flags, &priv_length);
+ hexdump(indent, "DSC private_data" , priv, priv_length);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_metadata:
+ {
+ struct mpeg_metadata_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_metadata_descriptor\n");
+ dx = mpeg_metadata_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_metadata_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_application_format:%04x\n",
+ dx->metadata_application_format);
+
+ struct mpeg_metadata_descriptor_application_format_identifier *id =
+ mpeg_metadata_descriptor_appid(dx);
+ if (id != NULL) {
+ iprintf(indent, "DSC application_format_id:%04x\n",
+ id->id);
+ }
+
+ struct mpeg_metadata_descriptor_format_identifier *did =
+ mpeg_metadata_descriptor_formid(dx);
+ if (did != NULL) {
+ iprintf(indent, "DSC mpeg_metadata_descriptor_format_id:%04x\n",
+ did->id);
+ }
+
+ struct mpeg_metadata_descriptor_flags *flags =
+ mpeg_metadata_descriptor_flags(dx);
+ if (flags != NULL) {
+ iprintf(indent, "DSC metadata_service_id:%i decoder_config_flags:%i dsm_cc_flag:%x\n",
+ flags->metadata_service_id,
+ flags->decoder_config_flags,
+ flags->dsm_cc_flag);
+
+ struct mpeg_metadata_descriptor_service_identifier *serviceid=
+ mpeg_metadata_descriptor_sevice_identifier(flags);
+ if (serviceid != NULL) {
+ hexdump(indent, "DSC service_id" ,
+ mpeg_metadata_descriptor_service_identifier_data(serviceid),
+ serviceid->service_identification_length);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config *dconfig=
+ mpeg_metadata_descriptor_decoder_config(flags);
+ if (dconfig != NULL) {
+ hexdump(indent, "DSC decoder_config" ,
+ mpeg_metadata_descriptor_decoder_config_data(dconfig),
+ dconfig->decoder_config_length);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config_id_record *dconfigid=
+ mpeg_metadata_descriptor_decoder_config_id_record(flags);
+ if (dconfigid != NULL) {
+ hexdump(indent, "DSC decoder_config" ,
+ mpeg_metadata_descriptor_decoder_config_id_record_data(dconfigid),
+ dconfigid->decoder_config_id_record_length);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config_service_id *dserviceid=
+ mpeg_metadata_descriptor_decoder_config_service_id(flags);
+ if (dserviceid != NULL) {
+ iprintf(indent, "DSC decoder config service_id:%04x\n",
+ dserviceid->decoder_config_metadata_service_id);
+ }
+
+ struct mpeg_metadata_descriptor_decoder_config_reserved *reserved=
+ mpeg_metadata_descriptor_decoder_config_reserved(flags);
+ if (reserved != NULL) {
+ hexdump(indent, "DSC reserved" ,
+ mpeg_metadata_descriptor_decoder_config_reserved_data(reserved),
+ reserved->reserved_data_length);
+ }
+
+ uint8_t *priv;
+ int priv_length;
+ priv = mpeg_metadata_descriptor_private_data(dx, flags, &priv_length);
+ hexdump(indent, "DSC private_data" , priv, priv_length);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_mpeg_metadata_std:
+ {
+ struct mpeg_metadata_std_descriptor *dx;
+
+ iprintf(indent, "DSC Decode mpeg_metadata_std_descriptor\n");
+ dx = mpeg_metadata_std_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX mpeg_metadata_std_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC metadata_input_leak_rate:%i metadata_buffer_size:%i metadata_output_leak_rate:%i\n",
+ dx->metadata_input_leak_rate,
+ dx->metadata_buffer_size,
+ dx->metadata_output_leak_rate);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ default:
+ switch(data_type) {
+ case DATA_TYPE_DVB:
+ parse_dvb_descriptor(d, indent, data_type);
+ return;
+
+ case DATA_TYPE_ATSC:
+ parse_atsc_descriptor(d, indent, data_type);
+ return;
+
+ default:
+ fprintf(stderr, "DSC XXXX Unknown descriptor_tag:0x%02x\n", d->tag);
+ hexdump(0, "DSC ", (uint8_t*) d, d->len+2);
+ return;
+ }
+ }
+}
+
+void parse_dvb_descriptor(struct descriptor *d, int indent, int data_type)
+{
+ (void) data_type;
+
+ switch(d->tag) {
+ case dtag_dvb_network_name:
+ {
+ struct dvb_network_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_network_name_descriptor\n");
+ dx = dvb_network_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_network_name_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC name:%.*s\n",
+ dvb_network_name_descriptor_name_length(dx),
+ dvb_network_name_descriptor_name(dx));
+ break;
+ }
+
+ case dtag_dvb_service_list:
+ {
+ struct dvb_service_list_descriptor *dx;
+ struct dvb_service_list_service *curs;
+
+ iprintf(indent, "DSC Decode dvb_service_list_descriptor\n");
+ dx = dvb_service_list_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_list_descriptor decode error\n");
+ return;
+ }
+ dvb_service_list_descriptor_services_for_each(dx, curs) {
+ iprintf(indent+1, "DSC service_id:0x%04x service_type:0x%02x\n",
+ curs->service_id, curs->service_type);
+ }
+ break;
+ }
+
+ case dtag_dvb_stuffing:
+ {
+ struct dvb_stuffing_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_stuffing_descriptor\n");
+ dx = dvb_stuffing_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_stuffing_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_stuffing_descriptor_data(dx),
+ dvb_stuffing_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_dvb_satellite_delivery_system:
+ {
+ struct dvb_satellite_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_satellite_delivery_descriptor\n");
+ dx = dvb_satellite_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_satellite_delivery_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC frequency:%i orbital_position:%i west_east:%i polarization:%i roll_off:%i modulation_system:%i modulation_type: %i symbol_rate:%i fec_inner:%i\n",
+ dx->frequency,
+ dx->orbital_position,
+ dx->west_east_flag,
+ dx->polarization,
+ dx->roll_off,
+ dx->modulation_system,
+ dx->modulation_type,
+ dx->symbol_rate,
+ dx->fec_inner);
+ break;
+ }
+
+ case dtag_dvb_cable_delivery_system:
+ {
+ struct dvb_cable_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_cable_delivery_descriptor\n");
+ dx = dvb_cable_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_cable_delivery_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC frequency:%i fec_outer:%i modulation:%i symbol_rate:%i fec_inner:%i\n",
+ dx->frequency, dx->fec_outer, dx->modulation,
+ dx->symbol_rate, dx->fec_inner);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_vbi_data:
+ {
+ struct dvb_vbi_data_descriptor *dx;
+ struct dvb_vbi_data_entry *cur;
+ struct dvb_vbi_data_x *curx;
+
+ iprintf(indent, "DSC Decode dvb_vbi_data_descriptor\n");
+ dx = dvb_vbi_data_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_vbi_data_descriptor decode error\n");
+ return;
+ }
+ dvb_vbi_data_descriptor_entries_for_each(dx, cur) {
+ curx = dvb_vbi_data_entry_data_x(cur);
+ iprintf(indent+1, "DSC data_service_id:0x%04x\n", cur->data_service_id);
+ if (cur == NULL) {
+ hexdump(indent+1, "DSC", dvb_vbi_data_entry_data(cur), cur->data_length);
+ } else {
+ iprintf(indent+1, "DSC field_parity:%i line_offset:%i\n",
+ curx->field_parity, curx->line_offset);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_vbi_teletext:
+ {
+ struct dvb_vbi_teletext_descriptor *dx;
+ struct dvb_vbi_teletext_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_vbi_teletext_descriptor\n");
+ dx = dvb_vbi_teletext_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_vbi_teletext_descriptor decode error\n");
+ return;
+ }
+ dvb_vbi_teletext_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1, "DSC language_code:%.3s type:%i magazine_number:%i page_number:%i\n",
+ cur->language_code,
+ cur->type, cur->magazine_number, cur->page_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_bouquet_name:
+ {
+ struct dvb_bouquet_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_bouquet_name_descriptor\n");
+ dx = dvb_bouquet_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_bouquet_name_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC name:%.*s\n",
+ dvb_bouquet_name_descriptor_name_length(dx),
+ dvb_bouquet_name_descriptor_name(dx));
+ break;
+ }
+
+ case dtag_dvb_service:
+ {
+ struct dvb_service_descriptor *dx;
+ struct dvb_service_descriptor_part2 *part2;
+
+ iprintf(indent, "DSC Decode dvb_service_descriptor\n");
+ dx = dvb_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_service_descriptor_part2(dx);
+ iprintf(indent, "DSC service_type:%02x provider_name:%.*s service_name:%.*s\n",
+ dx->service_type,
+ dx->service_provider_name_length,
+ dvb_service_descriptor_service_provider_name(dx),
+ part2->service_name_length,
+ dvb_service_descriptor_service_name(part2));
+ break;
+ }
+
+ case dtag_dvb_country_availability:
+ {
+ struct dvb_country_availability_descriptor *dx;
+ struct dvb_country_availability_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_country_availability_descriptor\n");
+ dx = dvb_country_availability_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_country_availability_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC country_availability_flag:%i\n", dx->country_availability_flag);
+ dvb_country_availability_descriptor_countries_for_each(dx, cur) {
+ iprintf(indent+1, "DSC country_code:%.3s\n", cur->country_code);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_linkage:
+ {
+ struct dvb_linkage_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_linkage_descriptor\n");
+ dx = dvb_linkage_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_linkage_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC transport_stream_id:0x%04x original_network_id:0x%04x service_id:0x%04x linkage_type:0x%02x\n",
+ dx->transport_stream_id, dx->original_network_id, dx->service_id, dx->linkage_type);
+ switch(dx->linkage_type) {
+ case 0x08:
+ {
+ struct dvb_linkage_data_08 *d08 = dvb_linkage_data_08(dx);
+ int network_id = dvb_linkage_data_08_network_id(dx, d08);
+ int initial_service_id = dvb_linkage_data_08_initial_service_id(dx, d08);
+ int length = 0;
+ uint8_t *data;
+
+ data = dvb_linkage_data_08_data(dx, d08, &length);
+ iprintf(indent, "DSC hand_over_type:%i origin_type:%i\n",
+ d08->hand_over_type, d08->origin_type);
+ if (network_id != -1) {
+ iprintf(indent, "DSC network_id:0x%04x\n", network_id);
+ }
+ if (initial_service_id != -1) {
+ iprintf(indent, "DSC initial_service_id:0x%04x\n", initial_service_id);
+ }
+ }
+
+ case 0x0b:
+ {
+ struct dvb_linkage_data_0b *data = dvb_linkage_data_0b(dx);
+ struct dvb_platform_id *platid;
+ struct dvb_platform_name *curplatname;
+
+ dvb_linkage_data_0b_platform_id_for_each(data, platid) {
+ iprintf(indent+1, "DSC platform_id:0x%06x\n", platid->platform_id);
+ dvb_platform_id_platform_name_for_each(platid, curplatname) {
+ iprintf(indent+2, "DSC language_code:%.3s platform_name:%.*s\n",
+ curplatname->language_code,
+ curplatname->platform_name_length, dvb_platform_name_text(curplatname));
+ }
+ }
+ break;
+ }
+
+ case 0x0c:
+ {
+ struct dvb_linkage_data_0c *data = dvb_linkage_data_0c(dx);
+
+ iprintf(indent, "DSC table_type:0x%02x\n", data->table_type);
+ if (dvb_linkage_data_0c_bouquet_id(data)) {
+ iprintf(indent, "DSC bouquet_id:0x%04x\n",
+ dvb_linkage_data_0c_bouquet_id(data));
+ }
+ break;
+ }
+
+ default:
+ hexdump(indent+1, "DSC", dvb_linkage_descriptor_data(dx), dvb_linkage_descriptor_data_length(dx));
+ break;
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_nvod_reference:
+ {
+ struct dvb_nvod_reference_descriptor *dx;
+ struct dvb_nvod_reference *cur;
+
+ iprintf(indent, "DSC Decode dvb_nvod_reference_descriptor\n");
+ dx = dvb_nvod_reference_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_nvod_reference_descriptor decode error\n");
+ return;
+ }
+ dvb_nvod_reference_descriptor_references_for_each(dx, cur) {
+ iprintf(indent+1, "DSC transport_stream_id:0x%04x original_network_id:0x%04x service_id:0x%04x\n",
+ cur->transport_stream_id, cur->original_network_id,
+ cur->service_id);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_time_shifted_service:
+ {
+ struct dvb_time_shifted_service_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_time_shifted_service_descriptor\n");
+ dx = dvb_time_shifted_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_time_shifted_service_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC reference_service_id:0x%04x\n", dx->reference_service_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_short_event:
+ {
+ struct dvb_short_event_descriptor *dx;
+ struct dvb_short_event_descriptor_part2 *part2;
+
+ iprintf(indent, "DSC Decode dvb_short_event_descriptor\n");
+ dx = dvb_short_event_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_short_event_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_short_event_descriptor_part2(dx);
+ iprintf(indent, "DSC language_code:%.3s event_name:%.*s text:%.*s\n",
+ dx->language_code,
+ dx->event_name_length, dvb_short_event_descriptor_event_name(dx),
+ part2->text_length, dvb_short_event_descriptor_text(part2));
+ break;
+ }
+
+ case dtag_dvb_extended_event:
+ {
+ struct dvb_extended_event_descriptor *dx;
+ struct dvb_extended_event_descriptor_part2 *part2;
+ struct dvb_extended_event_item *cur;
+
+ iprintf(indent, "DSC Decode dvb_extended_event_descriptor\n");
+ dx = dvb_extended_event_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_extended_event_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_extended_event_descriptor_part2(dx);
+ iprintf(indent, "DSC descriptor_number:%i last_descriptor_number:%i language_code:%.3s text:%.*s\n",
+ dx->descriptor_number, dx->last_descriptor_number,
+ dx->language_code,
+ part2->text_length, dvb_extended_event_descriptor_part2_text(part2));
+ dvb_extended_event_descriptor_items_for_each(dx, cur) {
+ struct dvb_extended_event_item_part2 *ipart2 =
+ dvb_extended_event_item_part2(cur);
+ iprintf(indent+1, "DSC description:%.*s item:%.*s\n",
+ cur->item_description_length, dvb_extended_event_item_description(cur),
+ ipart2->item_length, dvb_extended_event_item_part2_item(ipart2));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_time_shifted_event:
+ {
+ struct dvb_time_shifted_event_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_time_shifted_event_descriptor\n");
+ dx = dvb_time_shifted_event_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_time_shifted_event_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC reference_service_id:0x%04x reference_event_id:0x%04x\n",
+ dx->reference_service_id, dx->reference_event_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_component:
+ {
+ struct dvb_component_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_component_descriptor\n");
+ dx = dvb_component_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_component_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC stream_content:%i component_type:%i component_tag: %i language_code:%.3s, text:%.*s\n",
+ dx->stream_content,
+ dx->component_type,
+ dx->component_tag,
+ dx->language_code,
+ dvb_component_descriptor_text_length(dx),
+ dvb_component_descriptor_text(dx));
+ break;
+ }
+
+ case dtag_dvb_mosaic:
+ {
+ struct dvb_mosaic_descriptor *dx;
+ struct dvb_mosaic_info *curinfo;
+
+ iprintf(indent, "DSC Decode dvb_mosaic_descriptor\n");
+ dx = dvb_mosaic_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_mosaic_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC mosaic_entry_point:%i number_of_horiz_elementary_cells:%i number_of_vert_elementary_cells:%i\n",
+ dx->mosaic_entry_point, dx->number_of_horiz_elementary_cells,
+ dx->number_of_vert_elementary_cells);
+ dvb_mosaic_descriptor_infos_for_each(dx, curinfo) {
+ struct dvb_mosaic_info_part2 *part2;
+ struct dvb_mosaic_linkage *linkage;
+ struct dvb_mosaic_elementary_cell_field *curfield;
+
+ part2 = dvb_mosaic_info_part2(curinfo);
+ linkage = dvb_mosaic_linkage(part2);
+ iprintf(indent+1, "DSC logical_cell_id:%i logical_cell_presentation_info:%i cell_linkage_info:0x%02x\n",
+ curinfo->logical_cell_id, curinfo->logical_cell_presentation_info,
+ part2->cell_linkage_info);
+ if (linkage) {
+ switch(part2->cell_linkage_info) {
+ case 0x01:
+ iprintf(indent+1, "DSC bouquet_id:0x%04x\n",
+ linkage->u.linkage_01.bouquet_id);
+ break;
+
+ case 0x02:
+ iprintf(indent+1, "DSC original_network_id:0x%04x transport_stream_id:0x%04x service_id:0x%04x\n",
+ linkage->u.linkage_02.original_network_id,
+ linkage->u.linkage_02.transport_stream_id,
+ linkage->u.linkage_02.service_id);
+ break;
+
+ case 0x03:
+ iprintf(indent+1, "DSC original_network_id:0x%04x transport_stream_id:0x%04x service_id:0x%04x\n",
+ linkage->u.linkage_03.original_network_id,
+ linkage->u.linkage_03.transport_stream_id,
+ linkage->u.linkage_03.service_id);
+ break;
+
+ case 0x04:
+ iprintf(indent+1, "DSC original_network_id:0x%04x transport_stream_id:0x%04x service_id:0x%04x event_id:0x%04x\n",
+ linkage->u.linkage_04.original_network_id,
+ linkage->u.linkage_04.transport_stream_id,
+ linkage->u.linkage_04.service_id,
+ linkage->u.linkage_04.event_id);
+ break;
+ }
+ }
+
+ dvb_mosaic_info_fields_for_each(curinfo, curfield) {
+ iprintf(indent+2, "DSC elementary_cell_id:0x%02x\n",
+ curfield->elementary_cell_id);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_stream_identifier:
+ {
+ struct dvb_stream_identifier_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_stream_identifier_descriptor\n");
+ dx = dvb_stream_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_stream_identifier_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC component_tag:%i\n",
+ dx->component_tag);
+ break;
+ }
+
+ case dtag_dvb_ca_identifier:
+ {
+ struct dvb_ca_identifier_descriptor *dx;
+ int i;
+ uint16_t *ids;
+
+ iprintf(indent, "DSC Decode dvb_ca_identifier_descriptor\n");
+ dx = dvb_ca_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_ca_identifier_descriptor decode error\n");
+ return;
+ }
+ ids = dvb_ca_identifier_descriptor_ca_system_ids(dx);
+ for(i=0; i< dvb_ca_identifier_descriptor_ca_system_ids_count(dx); i++) {
+ iprintf(indent+i, "DSC system_id:0x%04x\n", ids[i]);
+ }
+ break;
+ }
+
+ case dtag_dvb_content:
+ {
+ struct dvb_content_descriptor *dx;
+ struct dvb_content_nibble *cur;
+
+ iprintf(indent, "DSC Decode dvb_content_descriptor\n");
+ dx = dvb_content_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_content_descriptor decode error\n");
+ return;
+ }
+ dvb_content_descriptor_nibbles_for_each(dx, cur) {
+ iprintf(indent+1, "DSC content_nibble_level_1:%i content_nibble_level_2:%i user_nibble_1:%i user_nibble_2:%i\n",
+ cur->content_nibble_level_1, cur->content_nibble_level_2,
+ cur->user_nibble_1, cur->user_nibble_2);
+ }
+ break;
+ }
+
+ case dtag_dvb_parental_rating:
+ {
+ struct dvb_parental_rating_descriptor *dx;
+ struct dvb_parental_rating *cur;
+
+ iprintf(indent, "DSC Decode dvb_parental_rating_descriptor\n");
+ dx = dvb_parental_rating_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_parental_rating_descriptor decode error\n");
+ return;
+ }
+ dvb_parental_rating_descriptor_ratings_for_each(dx, cur) {
+ iprintf(indent+1, "DSC country_code:%.3s rating:%i\n",
+ cur->country_code, cur->rating);
+ }
+ break;
+ }
+
+ case dtag_dvb_teletext:
+ {
+ struct dvb_teletext_descriptor *dx;
+ struct dvb_teletext_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_teletext_descriptor\n");
+ dx = dvb_teletext_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_teletext_descriptor decode error\n");
+ return;
+ }
+ dvb_teletext_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1, "DSC language_code:%.3s type:%i magazine_number:%i page_number:%i\n",
+ cur->language_code,
+ cur->type, cur->magazine_number, cur->page_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_telephone:
+ {
+ struct dvb_telephone_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_telephone_descriptor\n");
+ dx = dvb_telephone_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_telephone_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC foreign_availability:%i connection_type:%i country_prefix:%.*s "
+ "international_area_code:%.*s operator_code:%.*s national_area_code:%.*s core_number:%.*s\n",
+ dx->foreign_availability, dx->connection_type,
+ dx->country_prefix_length, dvb_telephone_descriptor_country_prefix(dx),
+ dx->international_area_code_length, dvb_telephone_descriptor_international_area_code(dx),
+ dx->operator_code_length, dvb_telephone_descriptor_operator_code(dx),
+ dx->national_area_code_length, dvb_telephone_descriptor_national_area_code(dx),
+ dx->core_number_length, dvb_telephone_descriptor_core_number(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_local_time_offset:
+ {
+ struct dvb_local_time_offset_descriptor *dx;
+ struct dvb_local_time_offset *cur;
+
+ iprintf(indent, "DSC Decode dvb_local_time_offset_descriptor\n");
+ dx = dvb_local_time_offset_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_local_time_offset_descriptor decode error\n");
+ return;
+ }
+ dvb_local_time_offset_descriptor_offsets_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC country_code:%.3s country_region_id:%i "
+ "local_time_offset_polarity:%i local_time_offset:%i "
+ "time_of_change:%i next_time_offset:%i\n",
+ cur->country_code, cur->country_region_id,
+ cur->local_time_offset_polarity,
+ dvbhhmm_to_seconds(cur->local_time_offset),
+ dvbdate_to_unixtime(cur->time_of_change),
+ dvbhhmm_to_seconds(cur->next_time_offset));
+ }
+ break;
+ }
+
+ case dtag_dvb_subtitling:
+ {
+ struct dvb_subtitling_descriptor *dx;
+ struct dvb_subtitling_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_subtitling_descriptor\n");
+ dx = dvb_subtitling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_subtitling_descriptor decode error\n");
+ return;
+ }
+ dvb_subtitling_descriptor_subtitles_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s subtitling_type:0x%02x composition_page_id:0x%04x ancillary_page_id:0x%04x\n",
+ cur->language_code, cur->subtitling_type,
+ cur->composition_page_id, cur->ancillary_page_id);
+ }
+ break;
+ }
+
+ case dtag_dvb_terrestial_delivery_system:
+ {
+ struct dvb_terrestrial_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_terrestrial_delivery_descriptor\n");
+ dx = dvb_terrestrial_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_terrestrial_delivery_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC centre_frequency:%i bandwidth:%i priority:%i "
+ "time_slicing_indicator:%i mpe_fec_indicator:%i constellation:%i "
+ "hierarchy_information:%i code_rate_hp_stream:%i "
+ "code_rate_lp_stream:%i guard_interval:%i transmission_mode:%i "
+ "other_frequency_flag:%i\n",
+ dx->centre_frequency, dx->bandwidth, dx->priority,
+ dx->time_slicing_indicator, dx->mpe_fec_indicator,
+ dx->constellation,
+ dx->hierarchy_information, dx->code_rate_hp_stream,
+ dx->code_rate_lp_stream, dx->guard_interval,
+ dx->transmission_mode, dx->other_frequency_flag);
+ break;
+ }
+
+ case dtag_dvb_multilingual_network_name:
+ {
+ struct dvb_multilingual_network_name_descriptor *dx;
+ struct dvb_multilingual_network_name *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_network_name_descriptor\n");
+ dx = dvb_multilingual_network_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_network_name_descriptor decode error\n");
+ return;
+ }
+ dvb_multilingual_network_name_descriptor_names_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s network_name:%.*s\n",
+ cur->language_code,
+ cur->network_name_length,
+ dvb_multilingual_network_name_name(cur));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_multilingual_bouquet_name:
+ {
+ struct dvb_multilingual_bouquet_name_descriptor *dx;
+ struct dvb_multilingual_bouquet_name *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_bouquet_name_descriptor\n");
+ dx = dvb_multilingual_bouquet_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_bouquet_name_descriptor decode error\n");
+ return;
+ }
+ dvb_multilingual_bouquet_name_descriptor_names_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s bouquet_name:%.*s\n",
+ cur->language_code,
+ cur->bouquet_name_length,
+ dvb_multilingual_bouquet_name_name(cur));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_multilingual_service_name:
+ {
+ struct dvb_multilingual_service_name_descriptor *dx;
+ struct dvb_multilingual_service_name *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_service_name_descriptor\n");
+ dx = dvb_multilingual_service_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_service_name_descriptor decode error\n");
+ return;
+ }
+ dvb_multilingual_service_name_descriptor_names_for_each(dx, cur) {
+ struct dvb_multilingual_service_name_part2 *part2;
+ part2 = dvb_multilingual_service_name_part2(cur);
+
+ iprintf(indent+1,
+ "DSC language_code:%.3s provider_name:%.*s service_name:%.*s\n",
+ cur->language_code,
+ cur->service_provider_name_length,
+ dvb_multilingual_service_name_service_provider_name(cur),
+ part2->service_name_length,
+ dvb_multilingual_service_name_service_name(part2));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_multilingual_component:
+ {
+ struct dvb_multilingual_component_descriptor *dx;
+ struct dvb_multilingual_component *cur;
+
+ iprintf(indent, "DSC Decode dvb_multilingual_component_descriptor\n");
+ dx = dvb_multilingual_component_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_multilingual_component_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC component_tag:%02x\n", dx->component_tag);
+ dvb_multilingual_component_descriptor_components_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s description:%.*s\n",
+ cur->language_code,
+ cur->text_description_length,
+ dvb_multilingual_component_text_char(cur));
+ }
+ break;
+ }
+
+ case dtag_dvb_private_data_specifier:
+ {
+ struct dvb_private_data_specifier_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_private_data_specifier_descriptor\n");
+ dx = dvb_private_data_specifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_private_data_specifier_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC private_data_specifier:0x%08x\n",
+ dx->private_data_specifier);
+ break;
+ }
+
+ case dtag_dvb_service_move:
+ {
+ struct dvb_service_move_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_service_move_descriptor\n");
+ dx = dvb_service_move_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_move_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC new_original_network_id:0x%04x new_transport_stream_id:0x%04x new_service_id:0x%04x\n",
+ dx->new_original_network_id, dx->new_transport_stream_id, dx->new_service_id);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_short_smoothing_buffer:
+ {
+ struct dvb_short_smoothing_buffer_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_short_smoothing_buffer_descriptor\n");
+ dx = dvb_short_smoothing_buffer_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_short_smoothing_buffer_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC sb_size:%i sb_leak_rate:%i\n",
+ dx->sb_size, dx->sb_leak_rate);
+ hexdump(indent, "DSC",
+ dvb_short_smoothing_buffer_descriptor_reserved(dx),
+ dvb_short_smoothing_buffer_descriptor_reserved_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_frequency_list:
+ {
+ struct dvb_frequency_list_descriptor *dx;
+ uint32_t *freqs;
+ int count;
+ int i;
+
+ iprintf(indent, "DSC Decode dvb_frequency_list_descriptor\n");
+ dx = dvb_frequency_list_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_frequency_list_descriptor decode error\n");
+ return;
+ }
+ iprintf(0, "DSC coding_type=%i\n", dx->coding_type);
+
+ freqs = dvb_frequency_list_descriptor_centre_frequencies(dx);
+ count = dvb_frequency_list_descriptor_centre_frequencies_count(dx);
+ for(i=0; i< count; i++) {
+ iprintf(indent+1, "DSC %i\n", freqs[i]);
+ }
+ break;
+ }
+
+ case dtag_dvb_partial_transport_stream:
+ {
+ struct dvb_partial_transport_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_partial_transport_stream_descriptor\n");
+ dx = dvb_partial_transport_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_partial_transport_stream_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC peak_rate:%i minimum_overall_smoothing_rate:%i maximum_overall_smoothing_rate:%i\n",
+ dx->peak_rate, dx->minimum_overall_smoothing_rate, dx->maximum_overall_smoothing_rate);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_data_broadcast:
+ {
+ struct dvb_data_broadcast_descriptor *dx;
+ struct dvb_data_broadcast_descriptor_part2 *part2;
+
+ iprintf(indent, "DSC Decode dvb_data_broadcast_descriptor\n");
+ dx = dvb_data_broadcast_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_data_broadcast_descriptor decode error\n");
+ return;
+ }
+ part2 = dvb_data_broadcast_descriptor_part2(dx);
+
+ iprintf(indent, "DSC data_broadcast_id:0x%04x component_tag:0x%02x selector:%.*s language_code:%.3s text:%.*s\n",
+ dx->data_broadcast_id, dx->component_tag,
+ dx->selector_length, dvb_data_broadcast_descriptor_selector(dx),
+ part2->language_code,
+ part2->text_length, dvb_data_broadcast_descriptor_part2_text(part2));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_scrambling:
+ {
+ struct dvb_scrambling_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_scrambling_descriptor\n");
+ dx = dvb_scrambling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_scrambling_descriptor decode error\n");
+ return;
+ }
+
+ iprintf(indent, "DSC scrambling_mode:0x%02x\n",
+ dx->scrambling_mode);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_data_broadcast_id:
+ {
+ struct dvb_data_broadcast_id_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_data_broadcast_id_descriptor\n");
+ dx = dvb_data_broadcast_id_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_data_broadcast_id_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC data_broadcast_id:0x%04x\n",
+ dx->data_broadcast_id);
+ hexdump(indent+1, "DSC",
+ dvb_data_broadcast_id_descriptor_id_selector_byte(dx),
+ dvb_data_broadcast_id_descriptor_id_selector_byte_length(dx));
+ break;
+ }
+
+ case dtag_dvb_transport_stream:
+ {
+ struct dvb_transport_stream_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_transport_stream_descriptor\n");
+ dx = dvb_transport_stream_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_transport_stream_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_transport_stream_descriptor_data(dx),
+ dvb_transport_stream_descriptor_data_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_dsng:
+ {
+ struct dvb_dsng_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_dsng_descriptor\n");
+ dx = dvb_dsng_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_dsng_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_dsng_descriptor_data(dx),
+ dvb_dsng_descriptor_data_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_pdc:
+ {
+ struct dvb_pdc_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_pdc_descriptor\n");
+ dx = dvb_pdc_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_pdc_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC programme_id_label:0x%06x\n",
+ dx->programme_id_label);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_ac3:
+ {
+ struct dvb_ac3_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_ac3_descriptor\n");
+ dx = dvb_ac3_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_ac3_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC ac3_type_flag:%i bsid_flag:%i mainid_flag:%i asvc_flag:%i\n",
+ dx->ac3_type_flag, dx->bsid_flag, dx->mainid_flag, dx->asvc_flag);
+ hexdump(indent+1, "DSC",
+ dvb_ac3_descriptor_additional_info(dx),
+ dvb_ac3_descriptor_additional_info_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_ancillary_data:
+ {
+ struct dvb_ancillary_data_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_ancillary_data_descriptor\n");
+ dx = dvb_ancillary_data_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_ancillary_data_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent, "DSC scale_factor_error_check:%i dab_ancillary_data:%i announcement_switching_data:%i extended_ancillary_data:%i dvd_video_ancillary_data:%i\n",
+ dx->scale_factor_error_check,
+ dx->dab_ancillary_data,
+ dx->announcement_switching_data,
+ dx->extended_ancillary_data,
+ dx->dvd_video_ancillary_data);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_cell_list:
+ {
+ struct dvb_cell_list_descriptor *dx;
+ struct dvb_cell_list_entry *cur;
+ struct dvb_subcell_list_entry *cur_subcell;
+
+ iprintf(indent, "DSC Decode dvb_cell_list_descriptor\n");
+ dx = dvb_cell_list_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_cell_list_descriptor decode error\n");
+ return;
+ }
+ dvb_cell_list_descriptor_cells_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC cell_id:%04x cell_latitude:%i cell_longitude:%i cell_extend_of_latitude:%i cell_extend_of_longitude:%i\n",
+ cur->cell_id,
+ cur->cell_latitude,
+ cur->cell_longitude,
+ cur->cell_extend_of_latitude,
+ cur->cell_extend_of_longitude);
+
+ dvb_cell_list_entry_subcells_for_each(cur, cur_subcell) {
+ iprintf(indent+2,
+ "DSC cell_id_extension:%04x subcell_latitude:%i subcell_longitude:%i subcell_extend_of_latitude:%i subcell_extend_of_longitude:%i\n",
+ cur_subcell->cell_id_extension,
+ cur_subcell->subcell_latitude,
+ cur_subcell->subcell_longitude,
+ cur_subcell->subcell_extend_of_latitude,
+ cur_subcell->subcell_extend_of_longitude);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_cell_frequency_link:
+ {
+ struct dvb_cell_frequency_link_descriptor *dx;
+ struct dvb_cell_frequency_link_cell *cur;
+ struct dvb_cell_frequency_link_cell_subcell *cur_subcell;
+
+ iprintf(indent, "DSC Decode dvb_cell_frequency_link_descriptor\n");
+ dx = dvb_cell_frequency_link_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_cell_frequency_link_descriptor decode error\n");
+ return;
+ }
+ dvb_cell_frequency_link_descriptor_cells_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC cell_id:%04x frequency:%i\n",
+ cur->cell_id,
+ cur->frequency);
+
+ dvb_cell_frequency_link_cell_subcells_for_each(cur, cur_subcell) {
+ iprintf(indent+2,
+ "DSC cell_id_extension:%04x transposer_frequency:%i\n",
+ cur_subcell->cell_id_extension,
+ cur_subcell->transposer_frequency);
+ }
+ }
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_announcement_support:
+ {
+ struct dvb_announcement_support_descriptor *dx;
+ struct dvb_announcement_support_entry *cur;
+ struct dvb_announcement_support_reference *ref;
+
+ iprintf(indent, "DSC Decode dvb_announcement_support_descriptor\n");
+ dx = dvb_announcement_support_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_announcement_support_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC announcement_support_indicator:%04x\n",
+ dx->announcement_support_indicator);
+
+ dvb_announcement_support_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC announcement_type:%i reference_type:%i\n",
+ cur->announcement_type,
+ cur->reference_type);
+
+ ref = dvb_announcement_support_entry_reference(cur);
+ if (ref) {
+ iprintf(indent+1,
+ "DSC original_network_id:%04x transport_stream_id:%04x service_id:%04x component_tag:%02x\n",
+ ref->original_network_id,
+ ref->transport_stream_id,
+ ref->service_id,
+ ref->component_tag);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_application_signalling:
+ {
+ struct dvb_application_signalling_descriptor *dx;
+ struct dvb_application_signalling_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_application_signalling_descriptor\n");
+ dx = dvb_application_signalling_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_application_signalling_descriptor decode error\n");
+ return;
+ }
+
+ dvb_application_signalling_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC application_type:%i AIT_version_number:%i\n",
+ cur->application_type,
+ cur->AIT_version_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_adaptation_field_data:
+ {
+ struct dvb_adaptation_field_data_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_adaptation_field_data_descriptor\n");
+ dx = dvb_adaptation_field_data_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_adaptation_field_data_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC announcement_switching_data:%i\n",
+ dx->announcement_switching_data);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_service_identifier:
+ {
+ struct dvb_service_identifier_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_service_identifier_descriptor\n");
+ dx = dvb_service_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_identifier_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_service_identifier_descriptor_identifier(dx),
+ dvb_service_identifier_descriptor_identifier_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_service_availability:
+ {
+ struct dvb_service_availability_descriptor *dx;
+ uint16_t *cellids;
+ int count;
+ int i;
+
+ iprintf(indent, "DSC Decode dvb_service_availability_descriptor\n");
+ dx = dvb_service_availability_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_service_availability_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent,
+ "DSC availability_flag:%i\n",
+ dx->availability_flag);
+
+ cellids = dvb_service_availability_descriptor_cell_ids(dx);
+ count = dvb_service_availability_descriptor_cell_ids_count(dx);
+ for(i=0; i< count; i++) {
+ iprintf(indent+1, "DSC", "%04x\n", cellids[i]);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_default_authority:
+ {
+ struct dvb_default_authority_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_default_authority_descriptor\n");
+ dx = dvb_default_authority_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_default_authority_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ dvb_default_authority_descriptor_name(dx),
+ dvb_default_authority_descriptor_name_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_related_content:
+ {
+ struct dvb_related_content_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_related_content_descriptor\n");
+ dx = dvb_related_content_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_related_content_descriptor decode error\n");
+ return;
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_tva_id:
+ {
+ struct dvb_tva_id_descriptor *dx;
+ struct dvb_tva_id_entry *cur;
+
+ iprintf(indent, "DSC Decode dvb_tva_id_descriptor\n");
+ dx = dvb_tva_id_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_tva_id_descriptor decode error\n");
+ return;
+ }
+
+ dvb_tva_id_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC tva_id:%04x running_status:%i\n",
+ cur->tva_id,
+ cur->running_status);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_content_identifier:
+ {
+ struct dvb_content_identifier_descriptor *dx;
+ struct dvb_content_identifier_entry *cur;
+ struct dvb_content_identifier_entry_data_0 *data0;
+ struct dvb_content_identifier_entry_data_1 *data1;
+
+ iprintf(indent, "DSC Decode dvb_tva_id_descriptor\n");
+ dx = dvb_content_identifier_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_content_identifier_descriptor decode error\n");
+ return;
+ }
+
+ dvb_content_identifier_descriptor_entries_for_each(dx, cur) {
+ iprintf(indent+1,
+ "DSC crid_type:%i crid_location:%i\n",
+ cur->crid_type,
+ cur->crid_location);
+
+ data0 = dvb_content_identifier_entry_data_0(cur);
+ if (data0) {
+ hexdump(indent, "DSC data0",
+ dvb_content_identifier_entry_data_0_data(data0),
+ data0->crid_length);
+ }
+
+ data1 = dvb_content_identifier_entry_data_1(cur);
+ if (data1) {
+ iprintf(indent+1,
+ "DSC crid_ref:%04x\n",
+ data1->crid_ref);
+ }
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_dvb_s2_satellite_delivery_descriptor:
+ {
+ struct dvb_s2_satellite_delivery_descriptor *dx;
+
+ iprintf(indent, "DSC Decode dvb_s2_satellite_delivery_descriptor\n");
+ dx = dvb_s2_satellite_delivery_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX dvb_s2_satellite_delivery_descriptor decode error\n");
+ return;
+ }
+
+ iprintf(indent,
+ "DSC scrambling_sequence_selector:%i multiple_input_stream:%i backwards_compatability:%i\n",
+ dx->scrambling_sequence_selector,
+ dx->multiple_input_stream,
+ dx->backwards_compatability);
+ if (dx->scrambling_sequence_selector) {
+ iprintf(indent,
+ "DSC scrambling_sequence_index:%i\n",
+ dvb_s2_satellite_delivery_descriptor_scrambling_sequence_index(dx));
+ }
+ if (dx->multiple_input_stream) {
+ iprintf(indent,
+ "DSC input_stream_id:%i\n",
+ dvb_s2_satellite_delivery_descriptor_input_stream_id(dx));
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ default:
+ fprintf(stderr, "DSC XXXX Unknown descriptor_tag:0x%02x\n", d->tag);
+ hexdump(0, "DSC ", (uint8_t*) d, d->len+2);
+ return;
+ }
+}
+
+void parse_atsc_descriptor(struct descriptor *d, int indent, int data_type)
+{
+ (void) data_type;
+
+ switch(d->tag) {
+ case dtag_atsc_stuffing:
+ {
+ struct atsc_stuffing_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_stuffing_descriptor\n");
+ dx = atsc_stuffing_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_stuffing_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ atsc_stuffing_descriptor_data(dx),
+ atsc_stuffing_descriptor_data_length(dx));
+ break;
+ }
+
+ case dtag_atsc_ac3_audio:
+ {
+ struct atsc_ac3_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_ac3_descriptor\n");
+ dx = atsc_ac3_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_ac3_descriptor decode error\n");
+ return;
+ }
+
+ iprintf(indent,
+ "DSC sample_rate_code:%i bsid:%i bit_rate_code:%i surround_mode:%i bsmod:%i num_channels:%i full_svc:%i\n",
+ dx->sample_rate_code,
+ dx->bsid,
+ dx->bit_rate_code,
+ dx->surround_mode,
+ dx->bsmod,
+ dx->num_channels,
+ dx->full_svc);
+
+ hexdump(indent+1, "DSC additional_info",
+ atsc_ac3_descriptor_additional_info(dx),
+ atsc_ac3_descriptor_additional_info_length(dx));
+ break;
+ }
+
+ case dtag_atsc_caption_service:
+ {
+ struct atsc_caption_service_descriptor *dx;
+ struct atsc_caption_service_entry *cur;
+ int idx;
+
+ iprintf(indent, "DSC Decode atsc_caption_service_descriptor\n");
+ dx = atsc_caption_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_caption_service_descriptor decode error\n");
+ return;
+ }
+
+ atsc_caption_service_descriptor_entries_for_each(dx, cur, idx) {
+ iprintf(indent+1,
+ "DSC language_code:%.3s digital_cc:%i value:%i easy_reader:%i wide_aspect_ratio:%i\n",
+ cur->language_code,
+ cur->digital_cc,
+ cur->value,
+ cur->easy_reader,
+ cur->wide_aspect_ratio);
+ }
+ break;
+ }
+
+ case dtag_atsc_content_advisory:
+ {
+ struct atsc_content_advisory_descriptor *dx;
+ struct atsc_content_advisory_entry *cure;
+ struct atsc_content_advisory_entry_dimension *curd;
+ struct atsc_content_advisory_entry_part2 *part2;
+ int eidx;
+ int didx;
+
+ iprintf(indent, "DSC Decode atsc_content_advisory_descriptor\n");
+ dx = atsc_content_advisory_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_content_advisory_descriptor decode error\n");
+ return;
+ }
+
+ atsc_content_advisory_descriptor_entries_for_each(dx, cure, eidx) {
+ iprintf(indent+1,
+ "DSC rating_region:%i\n",
+ cure->rating_region);
+
+ atsc_content_advisory_entry_dimensions_for_each(cure, curd, didx) {
+ iprintf(indent+2,
+ "DSC rating_dimension_j:%i rating_value:%i\n",
+ curd->rating_dimension_j,
+ curd->rating_value);
+ }
+
+ part2 = atsc_content_advisory_entry_part2(cure);
+
+ atsctextdump("DSC description:",
+ indent,
+ atsc_content_advisory_entry_part2_description(part2),
+ part2->rating_description_length);
+ }
+
+ break;
+ }
+
+ case dtag_atsc_extended_channel_name:
+ {
+ struct atsc_extended_channel_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_extended_channel_name_descriptor\n");
+ dx = atsc_extended_channel_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_extended_channel_name_descriptor decode error\n");
+ return;
+ }
+
+ atsctextdump("SCT text:", 1,
+ atsc_extended_channel_name_descriptor_text(dx),
+ atsc_extended_channel_name_descriptor_text_length(dx));
+ break;
+ }
+
+ case dtag_atsc_service_location:
+ {
+ struct atsc_service_location_descriptor *dx;
+ struct atsc_caption_service_location_element *cur;
+ int idx;
+
+ iprintf(indent, "DSC Decode atsc_service_location_descriptor\n");
+ dx = atsc_service_location_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_service_location_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent+1, "DSC PCR_PID:%04x\n", dx->PCR_PID);
+
+ atsc_service_location_descriptor_elements_for_each(dx, cur, idx) {
+ iprintf(indent+1, "DSC stream_type:%02x elementary_PID:%04x language_code:%.3s\n",
+ cur->stream_type,
+ cur->elementary_PID,
+ cur->language_code);
+ }
+ break;
+ }
+
+ case dtag_atsc_time_shifted_service:
+ {
+ struct atsc_time_shifted_service_descriptor *dx;
+ struct atsc_time_shifted_service *cur;
+ int idx;
+
+ iprintf(indent, "DSC Decode atsc_time_shifted_service_descriptor\n");
+ dx = atsc_time_shifted_service_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_time_shifted_service_descriptor decode error\n");
+ return;
+ }
+
+ atsc_time_shifted_service_descriptor_services_for_each(dx, cur, idx) {
+ iprintf(indent+1, "DSC time_shift:%i major_channel_number:%04x minor_channel_number:%04x\n",
+ cur->time_shift,
+ cur->major_channel_number,
+ cur->minor_channel_number);
+ }
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_component_name:
+ {
+ struct atsc_component_name_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_component_name_descriptor\n");
+ dx = atsc_component_name_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_component_name_descriptor decode error\n");
+ return;
+ }
+
+ atsctextdump("SCT name:", 1,
+ atsc_component_name_descriptor_text(dx),
+ atsc_component_name_descriptor_text_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_dcc_departing_request:
+ {
+ struct atsc_dcc_departing_request_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_dcc_departing_request_descriptor\n");
+ dx = atsc_dcc_departing_request_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_dcc_departing_request_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent+1, "DSC dcc_departing_request_type:%02x\n",
+ dx->dcc_departing_request_type);
+
+ atsctextdump("SCT text:", 1,
+ atsc_dcc_departing_request_descriptor_text(dx),
+ atsc_dcc_departing_request_descriptor_text_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_dcc_arriving_request:
+ {
+ struct atsc_dcc_arriving_request_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_dcc_arriving_request_descriptor\n");
+ dx = atsc_dcc_arriving_request_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_dcc_arriving_request_descriptor decode error\n");
+ return;
+ }
+ iprintf(indent+1, "DSC dcc_arriving_request_type:%02x\n",
+ dx->dcc_arriving_request_type);
+
+ atsctextdump("SCT text:", 1,
+ atsc_dcc_arriving_request_descriptor_text(dx),
+ atsc_dcc_arriving_request_descriptor_text_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_redistribution_control:
+ {
+ struct atsc_rc_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_rc_descriptor\n");
+ dx = atsc_rc_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_rc_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ atsc_rc_descriptor_info(dx),
+ atsc_rc_descriptor_info_length(dx));
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_genre:
+ {
+ struct atsc_genre_descriptor *dx;
+
+ iprintf(indent, "DSC Decode atsc_genre_descriptor\n");
+ dx = atsc_genre_descriptor_codec(d);
+ if (dx == NULL) {
+ fprintf(stderr, "DSC XXXX atsc_genre_descriptor decode error\n");
+ return;
+ }
+ hexdump(indent, "DSC",
+ atsc_genre_descriptor_attributes(dx),
+ dx->attribute_count);
+
+ hexdump(0, "XXX", (uint8_t*) d, d->len + 2);
+ getchar();
+ break;
+ }
+
+ case dtag_atsc_private_information:
+ // FIXME: whats the format?
+
+ case dtag_atsc_content_identifier:
+ // FIXME: whats the format?
+
+ default:
+ fprintf(stderr, "DSC XXXX Unknown descriptor_tag:0x%02x\n", d->tag);
+ hexdump(0, "DSC ", (uint8_t*) d, d->len+2);
+ return;
+ }
+}
+
+void iprintf(int indent, char *fmt, ...)
+{
+ va_list ap;
+
+ while(indent--) {
+ printf("\t");
+ }
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
+void hexdump(int indent, char *prefix, uint8_t *buf, int buflen)
+{
+ int i;
+ int j;
+ int max;
+ char line[512];
+
+ for(i=0; i< buflen; i+=16) {
+ max = 16;
+ if ((i + max) > buflen)
+ max = buflen - i;
+
+ memset(line, 0, sizeof(line));
+ memset(line + 4 + 48 + 1, ' ', 16);
+ sprintf(line, "%02x: ", i);
+ for(j=0; j<max; j++) {
+ sprintf(line + 4 + (j*3), "%02x", buf[i+j]);
+ if ((buf[i+j] > 31) && (buf[i+j] < 127))
+ line[4 + 48 + 1 + j] = buf[i+j];
+ else
+ line[4 + 48 + 1 + j] = '.';
+ }
+
+ for(j=0; j< 4 + 48; j++) {
+ if (!line[j])
+ line[j] = ' ';
+ }
+ line[4+48] = '|';
+
+ for(j=0; j < indent; j++) {
+ printf("\t");
+ }
+ printf("%s%s|\n", prefix, line);
+ }
+}
+
+void atsctextdump(char *header, int indent, struct atsc_text *atext, int len)
+{
+ struct atsc_text_string *cur_string;
+ struct atsc_text_string_segment *cur_segment;
+ int str_idx;
+ int seg_idx;
+
+ if (len == 0)
+ return;
+
+ atsc_text_strings_for_each(atext, cur_string, str_idx) {
+ iprintf(indent+1, "%s String %i language:%.3s\n", header, str_idx, cur_string->language_code);
+
+ atsc_text_string_segments_for_each(cur_string, cur_segment, seg_idx) {
+ iprintf(indent+2, "Segment %i compression_type:%i mode:%i\n",
+ seg_idx,
+ cur_segment->compression_type,
+ cur_segment->mode);
+
+ hexdump(indent+2, "rawbytes ",
+ atsc_text_string_segment_bytes(cur_segment),
+ cur_segment->number_bytes);
+
+ if (cur_segment->compression_type < 0x3e) {
+ uint8_t *decoded = NULL;
+ size_t decodedlen = 0;
+ size_t decodedpos = 0;
+
+ if (atsc_text_segment_decode(cur_segment,
+ &decoded,
+ &decodedlen,
+ &decodedpos) < 0) {
+ iprintf(indent+2, "Decode error\n");
+ } else {
+ hexdump(indent+2, "decoded ", decoded, decodedpos);
+ }
+ if (decoded)
+ free(decoded);
+ }
+ }
+ }
+}
diff --git a/test/lnb.c b/test/lnb.c
new file mode 100644
index 0000000..9052d1c
--- /dev/null
+++ b/test/lnb.c
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "lnb.h"
+
+static char *univ_desc[] = {
+ "Europe",
+ "10800 to 11800 MHz and 11600 to 12700 Mhz",
+ "Dual LO, loband 9750, hiband 10600 MHz",
+ (char *)NULL };
+
+static char *dbs_desc[] = {
+ "Expressvu, North America",
+ "12200 to 12700 MHz",
+ "Single LO, 11250 MHz",
+ (char *)NULL };
+
+static char *standard_desc[] = {
+ "10945 to 11450 Mhz",
+ "Single LO, 10000 Mhz",
+ (char *)NULL };
+
+static char *enhan_desc[] = {
+ "Astra",
+ "10700 to 11700 MHz",
+ "Single LO, 9750 MHz",
+ (char *)NULL };
+
+static char *cband_desc[] = {
+ "Big Dish",
+ "3700 to 4200 MHz",
+ "Single LO, 5150 Mhz",
+ (char *)NULL };
+
+static struct lnb_types_st lnbs[] = {
+ {"UNIVERSAL", univ_desc, 9750, 10600, 11700 },
+ {"DBS", dbs_desc, 11250, 0, 0 },
+ {"STANDARD", standard_desc, 10000, 0, 0 },
+ {"ENHANCED", enhan_desc, 9750, 0, 0 },
+ {"C-BAND", cband_desc, 5150, 0, 0 }
+};
+
+/* Enumerate through standard types of LNB's until NULL returned.
+ * Increment curno each time
+ */
+
+struct lnb_types_st *
+lnb_enum(int curno)
+{
+ if (curno >= (int) (sizeof(lnbs) / sizeof(lnbs[0])))
+ return (struct lnb_types_st *)NULL;
+ return &lnbs[curno];
+}
+
+/* Decode an lnb type, for example given on a command line
+ * If alpha and standard type, e.g. "Universal" then match that
+ * otherwise low[,high[,switch]]
+ */
+
+int
+lnb_decode(char *str, struct lnb_types_st *lnbp)
+{
+int i;
+char *cp, *np;
+
+ memset(lnbp, 0, sizeof(*lnbp));
+ cp = str;
+ while(*cp && isspace(*cp))
+ cp++;
+ if (isalpha(*cp)) {
+ for (i = 0; i < (int)(sizeof(lnbs) / sizeof(lnbs[0])); i++) {
+ if (!strcasecmp(lnbs[i].name, cp)) {
+ *lnbp = lnbs[i];
+ return 1;
+ }
+ }
+ return -1;
+ }
+ if (*cp == '\0' || !isdigit(*cp))
+ return -1;
+ lnbp->low_val = strtoul(cp, &np, 0);
+ if (lnbp->low_val == 0)
+ return -1;
+ cp = np;
+ while(*cp && (isspace(*cp) || *cp == ','))
+ cp++;
+ if (*cp == '\0')
+ return 1;
+ if (!isdigit(*cp))
+ return -1;
+ lnbp->high_val = strtoul(cp, &np, 0);
+ cp = np;
+ while(*cp && (isspace(*cp) || *cp == ','))
+ cp++;
+ if (*cp == '\0')
+ return 1;
+ if (!isdigit(*cp))
+ return -1;
+ lnbp->switch_val = strtoul(cp, NULL, 0);
+ return 1;
+}
diff --git a/test/lnb.h b/test/lnb.h
new file mode 100644
index 0000000..6370fd4
--- /dev/null
+++ b/test/lnb.h
@@ -0,0 +1,22 @@
+struct lnb_types_st {
+ char *name;
+ char **desc;
+ unsigned long low_val;
+ unsigned long high_val; /* zero indicates no hiband */
+ unsigned long switch_val; /* zero indicates no hiband */
+};
+
+/* Enumerate through standard types of LNB's until NULL returned.
+ * Increment curno each time
+ */
+
+struct lnb_types_st *
+lnb_enum(int curno);
+
+/* Decode an lnb type, for example given on a command line
+ * If alpha and standard type, e.g. "Universal" then match that
+ * otherwise low[,high[,switch]]
+ */
+
+int
+lnb_decode(char *str, struct lnb_types_st *lnbp);
diff --git a/test/sendburst.c b/test/sendburst.c
index a96b68c..b19df37 100644
--- a/test/sendburst.c
+++ b/test/sendburst.c
@@ -1,8 +1,9 @@
-/*
- * Test sending the burst mini command A/B on a SAT frontend.
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX sendburst {a|b}
- */
+#define USAGE \
+"\n" \
+"\nTest sending the burst mini command A/B on a SAT frontend." \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX sendburst {a|b}" \
+"\n"
#include <stdlib.h>
#include <stdio.h>
@@ -22,7 +23,7 @@ int main (int argc, char **argv)
int fd, r;
if (argc != 2 || (strcmp(argv[1], "a") && strcmp(argv[1], "b"))) {
- fprintf (stderr, "usage: %s <a|b>\n", argv[0]);
+ fprintf (stderr, "usage: %s <a|b>\n" USAGE, argv[0]);
return 1;
}
@@ -52,4 +53,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/test/set22k.c b/test/set22k.c
index 51ffa1c..a9f0d8c 100644
--- a/test/set22k.c
+++ b/test/set22k.c
@@ -1,10 +1,11 @@
-/*
- * Test switching the 22kHz tone signal on and off on a SAT frontend.
- * (Note: DiSEqC equipment ignores this after it has once seen a diseqc
- * sequence; reload the driver or unplug/replug the SAT cable to reset.)
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX set22k {on|off}
- */
+#define USAGE \
+"\n" \
+"\nTest switching the 22kHz tone signal on and off on a SAT frontend." \
+"\n(Note: DiSEqC equipment ignores this after it has once seen a diseqc" \
+"\n sequence; reload the driver or unplug/replug the SAT cable to reset.)" \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX set22k {on|off}" \
+"\n"
#include <stdlib.h>
#include <stdio.h>
@@ -24,7 +25,7 @@ int main (int argc, char **argv)
int fd, r;
if (argc != 2 || (strcmp(argv[1], "on") && strcmp(argv[1], "off"))) {
- fprintf (stderr, "usage: %s <on|off>\n", argv[0]);
+ fprintf (stderr, "usage: %s <on|off>\n" USAGE, argv[0]);
return 1;
}
if (getenv("FRONTEND"))
@@ -47,4 +48,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/test/setpid.c b/test/setpid.c
index fa0333c..a2d42cf 100644
--- a/test/setpid.c
+++ b/test/setpid.c
@@ -1,9 +1,10 @@
-/*
- * Set video and audio PIDs in the demux; useful only if you have
- * a hardware MPEG decoder and you're tuned to a transport stream.
- *
- * usage: DEMUX=/dev/dvb/adapterX/demuxX setpid video_pid audio_pid
- */
+#define USAGE \
+"\n" \
+"\nSet video and audio PIDs in the demux; useful only if you have" \
+"\na hardware MPEG decoder and you're tuned to a transport stream." \
+"\n" \
+"\nusage: DEMUX=/dev/dvb/adapterX/demuxX setpid video_pid audio_pid" \
+"\n"
#include <unistd.h>
#include <stdlib.h>
@@ -69,7 +70,7 @@ int main (int argc, char **argv)
int video_pid, audio_pid;
if (argc != 3) {
- printf ("\nusage: %s <video pid> <audio pid>\n\n", argv[0]);
+ printf ("\nusage: %s <video pid> <audio pid>\n\n" USAGE, argv[0]);
exit (1);
}
if (getenv("DEMUX"))
@@ -83,5 +84,3 @@ int main (int argc, char **argv)
return 0;
}
-
-
diff --git a/test/setvoltage.c b/test/setvoltage.c
index 1d14a4c..80f7688 100644
--- a/test/setvoltage.c
+++ b/test/setvoltage.c
@@ -1,10 +1,11 @@
-/*
- * Test switching the voltage signal high and low on a SAT frontend.
- * (Note: DiSEqC equipment ignores this after it has once seen a diseqc
- * sequence; reload the driver or unplug/replug the SAT cable to reset.)
- *
- * usage: FRONTEND=/dev/dvb/adapterX/frontendX setvoltage {13|18}
- */
+#define USAGE \
+"\n" \
+"\nTest switching the voltage signal high and low on a SAT frontend." \
+"\n(Note: DiSEqC equipment ignores this after it has once seen a diseqc" \
+"\n sequence; reload the driver or unplug/replug the SAT cable to reset.)" \
+"\n" \
+"\nusage: FRONTEND=/dev/dvb/adapterX/frontendX setvoltage {13|18}" \
+"\n"
#include <stdlib.h>
#include <stdio.h>
@@ -23,7 +24,7 @@ int main (int argc, char **argv)
int fd, r;
if (argc != 2 || (strcmp(argv[1], "13") && strcmp(argv[1], "18"))) {
- fprintf (stderr, "usage: %s <13|18>\n", argv[0]);
+ fprintf (stderr, "usage: %s <13|18>\n" USAGE, argv[0]);
return -1;
}
if (getenv("FRONTEND"))
@@ -44,4 +45,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/test/szap2.c b/test/szap2.c
new file mode 100644
index 0000000..e470229
--- /dev/null
+++ b/test/szap2.c
@@ -0,0 +1,767 @@
+/* szap -- simple zapping tool for the Linux DVB API
+ *
+ * szap operates on VDR (http://www.cadsoft.de/people/kls/vdr/index.htm)
+ * satellite channel lists (e.g. from http://www.dxandy.de/cgi-bin/dvbchan.pl).
+ * szap assumes you have a "Universal LNB" (i.e. with LOFs 9750/10600 MHz).
+ *
+ * Compilation: `gcc -Wall -I../../ost/include -O2 szap.c -o szap`
+ * or, if your DVB driver is in the kernel source tree:
+ * `gcc -Wall -DDVB_IN_KERNEL -O2 szap.c -o szap`
+ *
+ * Copyright (C) 2001 Johannes Stezenbach (js@convergence.de)
+ * for convergence integrated media
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <stdint.h>
+#include <sys/time.h>
+
+#include "../include/frontend.h"
+#include "../include/dmx.h"
+#include "../include/audio.h"
+#include "../include/version.h"
+#include "lnb.h"
+
+#ifndef TRUE
+#define TRUE (1==1)
+#endif
+#ifndef FALSE
+#define FALSE (1==0)
+#endif
+
+/* location of channel list file */
+#define CHANNEL_FILE "channels.conf"
+
+/* one line of the VDR channel file has the following format:
+ * ^name:frequency_MHz:polarization:sat_no:symbolrate:vpid:apid:?:service_id$
+ */
+
+
+#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d"
+#define DEMUXDEVICE "/dev/dvb/adapter%d/demux%d"
+#define AUDIODEVICE "/dev/dvb/adapter%d/audio%d"
+
+static struct lnb_types_st lnb_type;
+
+static int exit_after_tuning;
+static int interactive;
+
+static char *usage_str =
+ "\nusage: szap -q\n"
+ " list known channels\n"
+ " szap [options] {-n channel-number|channel_name}\n"
+ " zap to channel via number or full name (case insensitive)\n"
+ " -a number : use given adapter (default 0)\n"
+ " -f number : use given frontend (default 0)\n"
+ " -d number : use given demux (default 0)\n"
+ " -c file : read channels list from 'file'\n"
+ " -b : enable Audio Bypass (default no)\n"
+ " -x : exit after tuning\n"
+ " -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n"
+ " -l lnb-type (DVB-S Only) (use -l help to print types) or \n"
+ " -l low[,high[,switch]] in Mhz\n"
+ " -i : run interactively, allowing you to type in channel names\n"
+ " -p : add pat and pmt to TS recording (implies -r)\n"
+ " or -n numbers for zapping\n"
+ " -t : delivery system type DVB-S=0, DSS=1, DVB-S2=2\n";
+
+static int set_demux(int dmxfd, int pid, int pes_type, int dvr)
+{
+ struct dmx_pes_filter_params pesfilter;
+
+ if (pid < 0 || pid >= 0x1fff) /* ignore this pid to allow radio services */
+ return TRUE;
+
+ if (dvr) {
+ int buffersize = 64 * 1024;
+ if (ioctl(dmxfd, DMX_SET_BUFFER_SIZE, buffersize) == -1)
+ perror("DMX_SET_BUFFER_SIZE failed");
+ }
+
+ pesfilter.pid = pid;
+ pesfilter.input = DMX_IN_FRONTEND;
+ pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER;
+ pesfilter.pes_type = pes_type;
+ pesfilter.flags = DMX_IMMEDIATE_START;
+
+ if (ioctl(dmxfd, DMX_SET_PES_FILTER, &pesfilter) == -1) {
+ fprintf(stderr, "DMX_SET_PES_FILTER failed "
+ "(PID = 0x%04x): %d %m\n", pid, errno);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int get_pmt_pid(char *dmxdev, int sid)
+{
+ int patfd, count;
+ int pmt_pid = 0;
+ int patread = 0;
+ int section_length;
+ unsigned char buft[4096];
+ unsigned char *buf = buft;
+ struct dmx_sct_filter_params f;
+
+ memset(&f, 0, sizeof(f));
+ f.pid = 0;
+ f.filter.filter[0] = 0x00;
+ f.filter.mask[0] = 0xff;
+ f.timeout = 0;
+ f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC;
+
+ if ((patfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("openening pat demux failed");
+ return -1;
+ }
+
+ if (ioctl(patfd, DMX_SET_FILTER, &f) == -1) {
+ perror("ioctl DMX_SET_FILTER failed");
+ close(patfd);
+ return -1;
+ }
+
+ while (!patread) {
+ if (((count = read(patfd, buf, sizeof(buft))) < 0) && errno == EOVERFLOW)
+ count = read(patfd, buf, sizeof(buft));
+ if (count < 0) {
+ perror("read_sections: read error");
+ close(patfd);
+ return -1;
+ }
+
+ section_length = ((buf[1] & 0x0f) << 8) | buf[2];
+ if (count != section_length + 3)
+ continue;
+
+ buf += 8;
+ section_length -= 8;
+
+ patread = 1; /* assumes one section contains the whole pat */
+ while (section_length > 0) {
+ int service_id = (buf[0] << 8) | buf[1];
+ if (service_id == sid) {
+ pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3];
+ section_length = 0;
+ }
+ buf += 4;
+ section_length -= 4;
+ }
+ }
+ close(patfd);
+ return pmt_pid;
+}
+
+struct diseqc_cmd {
+ struct dvb_diseqc_master_cmd cmd;
+ uint32_t wait;
+};
+
+void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
+ fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
+{
+ if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
+ perror("FE_SET_TONE failed");
+ if (ioctl(fd, FE_SET_VOLTAGE, v) == -1)
+ perror("FE_SET_VOLTAGE failed");
+ usleep(15 * 1000);
+ if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1)
+ perror("FE_DISEQC_SEND_MASTER_CMD failed");
+ usleep(cmd->wait * 1000);
+ usleep(15 * 1000);
+ if (ioctl(fd, FE_DISEQC_SEND_BURST, b) == -1)
+ perror("FE_DISEQC_SEND_BURST failed");
+ usleep(15 * 1000);
+ if (ioctl(fd, FE_SET_TONE, t) == -1)
+ perror("FE_SET_TONE failed");
+}
+
+
+
+
+/* digital satellite equipment control,
+ * specification is available from http://www.eutelsat.com/
+ */
+static int diseqc(int secfd, int sat_no, int pol_vert, int hi_band)
+{
+ struct diseqc_cmd cmd =
+ { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
+
+ /**
+ * param: high nibble: reset bits, low nibble set bits,
+ * bits are: option, position, polarizaion, band
+ */
+ cmd.cmd.msg[3] =
+ 0xf0 | (((sat_no * 4) & 0x0f) | (hi_band ? 1 : 0) | (pol_vert ? 0 : 2));
+
+ diseqc_send_msg(secfd, pol_vert ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18,
+ &cmd, hi_band ? SEC_TONE_ON : SEC_TONE_OFF,
+ (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
+
+ return TRUE;
+}
+
+#define DVBS 0
+#define DSS 1
+#define DVBS2 2
+
+static int do_tune(int fefd, unsigned int ifreq, unsigned int sr, unsigned int delsys)
+{
+ /* API Major=3, Minor=1 */
+ struct dvb_frontend_parameters tuneto;
+ struct dvb_frontend_event ev;
+ /* API Major=3, Minor=2 */
+ struct dvbfe_params fe_params;
+
+ /* discard stale QPSK events */
+ while (1) {
+ if (ioctl(fefd, FE_GET_EVENT, &ev) == -1)
+ break;
+ }
+
+ if ((DVB_API_VERSION == 3) && (DVB_API_VERSION_MINOR == 3)) {
+ printf("\n%s: API version=%d, delivery system = %d\n", __func__, DVB_API_VERSION_MINOR, delsys);
+
+ fe_params.frequency = ifreq;
+ fe_params.inversion = INVERSION_AUTO;
+
+ switch (delsys) {
+ case DVBS:
+ fe_params.delsys.dvbs.symbol_rate = sr;
+ fe_params.delsys.dvbs.fec = FEC_AUTO;
+ printf("%s: Frequency = %d, Srate = %d\n",
+ __func__, fe_params.frequency, fe_params.delsys.dvbs.symbol_rate);
+ break;
+ case DSS:
+ fe_params.delsys.dss.symbol_rate = sr;
+ fe_params.delsys.dss.fec = FEC_AUTO;
+ printf("%s: Frequency = %d, Srate = %d\n",
+ __func__, fe_params.frequency, fe_params.delsys.dss.symbol_rate);
+ break;
+ case DVBS2:
+ fe_params.delsys.dvbs2.symbol_rate = sr;
+ fe_params.delsys.dvbs2.fec = FEC_AUTO;
+ printf("%s: Frequency = %d, Srate = %d\n",
+ __func__, fe_params.frequency, fe_params.delsys.dvbs2.symbol_rate);
+ break;
+ default:
+ return -EINVAL;
+ }
+ printf("%s: Frequency = %d, Srate = %d\n\n\n",
+ __func__, fe_params.frequency, fe_params.delsys.dvbs.symbol_rate);
+
+ if (ioctl(fefd, DVBFE_SET_PARAMS, &fe_params) == -1) {
+ perror("DVBFE_SET_PARAMS failed");
+ return FALSE;
+ }
+
+ } else if ((DVB_API_VERSION == 3) && (DVB_API_VERSION_MINOR == 1)){
+ tuneto.frequency = ifreq;
+ tuneto.inversion = INVERSION_AUTO;
+ tuneto.u.qpsk.symbol_rate = sr;
+ tuneto.u.qpsk.fec_inner = FEC_AUTO;
+ if (ioctl(fefd, FE_SET_FRONTEND, &tuneto) == -1) {
+ perror("FE_SET_FRONTEND failed");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+static
+int check_frontend (int fe_fd, int dvr)
+{
+ (void)dvr;
+ fe_status_t status;
+ uint16_t snr, signal;
+ uint32_t ber, uncorrected_blocks;
+ int timeout = 0;
+
+ do {
+ if (ioctl(fe_fd, FE_READ_STATUS, &status) == -1)
+ perror("FE_READ_STATUS failed");
+ /* some frontends might not support all these ioctls, thus we
+ * avoid printing errors
+ */
+ if (ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1)
+ signal = -2;
+ if (ioctl(fe_fd, FE_READ_SNR, &snr) == -1)
+ snr = -2;
+ if (ioctl(fe_fd, FE_READ_BER, &ber) == -1)
+ ber = -2;
+ if (ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1)
+ uncorrected_blocks = -2;
+
+ printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
+ status, signal, snr, ber, uncorrected_blocks);
+
+ if (status & FE_HAS_LOCK)
+ printf("FE_HAS_LOCK");
+ printf("\n");
+
+ if (exit_after_tuning && ((status & FE_HAS_LOCK) || (++timeout >= 10)))
+ break;
+
+ usleep(1000000);
+ } while (1);
+
+ return 0;
+}
+
+
+static
+int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux,
+ unsigned int sat_no, unsigned int freq, unsigned int pol,
+ unsigned int sr, unsigned int vpid, unsigned int apid, int sid,
+ int dvr, int rec_psi, int bypass, unsigned int delsys)
+{
+ char fedev[128], dmxdev[128], auddev[128];
+ static int fefd, dmxfda, dmxfdv, audiofd = -1, patfd, pmtfd;
+ int pmtpid;
+ uint32_t ifreq;
+ int hiband, result;
+ enum dvbfe_delsys delivery;
+
+ switch (delsys) {
+ case DVBS:
+ printf("Delivery system=DVB-S\n");
+ delivery = DVBFE_DELSYS_DVBS;
+ break;
+ case DSS:
+ printf("Delivery system=DSS\n");
+ delivery = DVBFE_DELSYS_DSS;
+ break;
+ case DVBS2:
+ printf("Delivery system=DVB-S2\n");
+ delivery = DVBFE_DELSYS_DVBS2;
+ break;
+ default:
+ printf("Unsupported delivery system\n");
+ return -EINVAL;
+ }
+
+ if (!fefd) {
+ snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend);
+ snprintf(dmxdev, sizeof(dmxdev), DEMUXDEVICE, adapter, demux);
+ snprintf(auddev, sizeof(auddev), AUDIODEVICE, adapter, demux);
+ printf("using '%s' and '%s'\n", fedev, dmxdev);
+
+ if ((fefd = open(fedev, O_RDWR | O_NONBLOCK)) < 0) {
+ perror("opening frontend failed");
+ return FALSE;
+ }
+ result = ioctl(fefd, DVBFE_SET_DELSYS, &delivery);
+ if (result < 0) {
+ perror("ioctl DVBFE_SET_DELSYS failed");
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((dmxfdv = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening video demux failed");
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((dmxfda = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening audio demux failed");
+ close(fefd);
+ return FALSE;
+ }
+
+ if (dvr == 0) /* DMX_OUT_DECODER */
+ audiofd = open(auddev, O_RDWR);
+
+ if (rec_psi){
+ if ((patfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening pat demux failed");
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ return FALSE;
+ }
+
+ if ((pmtfd = open(dmxdev, O_RDWR)) < 0) {
+ perror("opening pmt demux failed");
+ close(patfd);
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ return FALSE;
+ }
+ }
+ }
+
+ hiband = 0;
+ if (lnb_type.switch_val && lnb_type.high_val &&
+ freq >= lnb_type.switch_val)
+ hiband = 1;
+
+ if (hiband)
+ ifreq = freq - lnb_type.high_val;
+ else {
+ if (freq < lnb_type.low_val)
+ ifreq = lnb_type.low_val - freq;
+ else
+ ifreq = freq - lnb_type.low_val;
+ }
+ result = FALSE;
+
+ if (diseqc(fefd, sat_no, pol, hiband))
+ if (do_tune(fefd, ifreq, sr, delsys))
+ if (set_demux(dmxfdv, vpid, DMX_PES_VIDEO, dvr))
+ if (audiofd >= 0)
+ (void)ioctl(audiofd, AUDIO_SET_BYPASS_MODE, bypass);
+ if (set_demux(dmxfda, apid, DMX_PES_AUDIO, dvr)) {
+ if (rec_psi) {
+ pmtpid = get_pmt_pid(dmxdev, sid);
+ if (pmtpid < 0) {
+ result = FALSE;
+ }
+ if (pmtpid == 0) {
+ fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid);
+ result = FALSE;
+ }
+ if (set_demux(patfd, 0, DMX_PES_OTHER, dvr))
+ if (set_demux(pmtfd, pmtpid, DMX_PES_OTHER, dvr))
+ result = TRUE;
+ } else {
+ result = TRUE;
+ }
+ }
+
+ check_frontend (fefd, dvr);
+
+ if (!interactive) {
+ close(patfd);
+ close(pmtfd);
+ if (audiofd >= 0)
+ close(audiofd);
+ close(dmxfda);
+ close(dmxfdv);
+ close(fefd);
+ }
+
+ return result;
+}
+
+
+static int read_channels(const char *filename, int list_channels,
+ uint32_t chan_no, const char *chan_name,
+ unsigned int adapter, unsigned int frontend,
+ unsigned int demux, int dvr, int rec_psi,
+ int bypass, unsigned int delsys)
+{
+ FILE *cfp;
+ char buf[4096];
+ char inp[256];
+ char *field, *tmp, *p;
+ unsigned int line;
+ unsigned int freq, pol, sat_no, sr, vpid, apid, sid;
+ int ret;
+
+again:
+ line = 0;
+ if (!(cfp = fopen(filename, "r"))) {
+ fprintf(stderr, "error opening channel list '%s': %d %m\n",
+ filename, errno);
+ return FALSE;
+ }
+
+ if (interactive) {
+ fprintf(stderr, "\n>>> ");
+ if (!fgets(inp, sizeof(inp), stdin)) {
+ printf("\n");
+ return -1;
+ }
+ if (inp[0] == '-' && inp[1] == 'n') {
+ chan_no = strtoul(inp+2, NULL, 0);
+ chan_name = NULL;
+ if (!chan_no) {
+ fprintf(stderr, "bad channel number\n");
+ goto again;
+ }
+ } else {
+ p = strchr(inp, '\n');
+ if (p)
+ *p = '\0';
+ chan_name = inp;
+ chan_no = 0;
+ }
+ }
+
+ while (!feof(cfp)) {
+ if (fgets(buf, sizeof(buf), cfp)) {
+ line++;
+
+ if (chan_no && chan_no != line)
+ continue;
+
+ tmp = buf;
+ field = strsep(&tmp, ":");
+
+ if (!field)
+ goto syntax_err;
+
+ if (list_channels) {
+ printf("%03u %s\n", line, field);
+ continue;
+ }
+
+ if (chan_name && strcasecmp(chan_name, field) != 0)
+ continue;
+
+ printf("zapping to %d '%s':\n", line, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ freq = strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ pol = (field[0] == 'h' ? 0 : 1);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sat_no = strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sr = strtoul(field, NULL, 0) * 1000;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ vpid = strtoul(field, NULL, 0);
+ if (!vpid)
+ vpid = 0x1fff;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ p = strchr(field, ';');
+
+ if (p) {
+ *p = '\0';
+ p++;
+ if (bypass) {
+ if (!p || !*p)
+ goto syntax_err;
+ field = p;
+ }
+ }
+
+ apid = strtoul(field, NULL, 0);
+ if (!apid)
+ apid = 0x1fff;
+
+ if (!(field = strsep(&tmp, ":")))
+ goto syntax_err;
+
+ sid = strtoul(field, NULL, 0);
+
+ printf("sat %u, frequency = %u MHz %c, symbolrate %u, "
+ "vpid = 0x%04x, apid = 0x%04x sid = 0x%04x\n",
+ sat_no, freq, pol ? 'V' : 'H', sr, vpid, apid, sid);
+
+ fclose(cfp);
+
+ ret = zap_to(adapter, frontend, demux, sat_no, freq * 1000,
+ pol, sr, vpid, apid, sid, dvr, rec_psi, bypass, delsys);
+ if (interactive)
+ goto again;
+
+ if (ret)
+ return TRUE;
+
+ return FALSE;
+
+syntax_err:
+ fprintf(stderr, "syntax error in line %u: '%s'\n", line, buf);
+ } else if (ferror(cfp)) {
+ fprintf(stderr, "error reading channel list '%s': %d %m\n",
+ filename, errno);
+ fclose(cfp);
+ return FALSE;
+ } else
+ break;
+ }
+
+ fclose(cfp);
+
+ if (!list_channels) {
+ fprintf(stderr, "channel not found\n");
+
+ if (!interactive)
+ return FALSE;
+ }
+ if (interactive)
+ goto again;
+
+ return TRUE;
+}
+
+
+void
+bad_usage(char *pname, int prlnb)
+{
+ int i;
+ struct lnb_types_st *lnbp;
+ char **cp;
+
+ if (!prlnb) {
+ fprintf (stderr, usage_str, pname);
+ } else {
+ i = 0;
+ fprintf(stderr, "-l <lnb-type> or -l low[,high[,switch]] in Mhz\nwhere <lnb-type> is:\n");
+ while(NULL != (lnbp = lnb_enum(i))) {
+ fprintf (stderr, "%s\n", lnbp->name);
+ for (cp = lnbp->desc; *cp ; cp++) {
+ fprintf (stderr, " %s\n", *cp);
+ }
+ i++;
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ const char *home;
+ char chanfile[2 * PATH_MAX];
+ int list_channels = 0;
+ unsigned int chan_no = 0;
+ const char *chan_name = NULL;
+ unsigned int adapter = 0, frontend = 0, demux = 0, dvr = 0, rec_psi = 0, delsys = 0;
+ int bypass = 0;
+ int opt, copt = 0;
+
+ lnb_type = *lnb_enum(0);
+ while ((opt = getopt(argc, argv, "hqrpn:a:f:d:t:c:l:xib")) != -1) {
+ switch (opt) {
+ case '?':
+ case 'h':
+ default:
+ bad_usage(argv[0], 0);
+ case 'b':
+ bypass = 1;
+ break;
+ case 'q':
+ list_channels = 1;
+ break;
+ case 'r':
+ dvr = 1;
+ break;
+ case 'n':
+ chan_no = strtoul(optarg, NULL, 0);
+ break;
+ case 'a':
+ adapter = strtoul(optarg, NULL, 0);
+ break;
+ case 'f':
+ frontend = strtoul(optarg, NULL, 0);
+ break;
+ case 'p':
+ rec_psi = 1;
+ break;
+ case 'd':
+ demux = strtoul(optarg, NULL, 0);
+ break;
+ case 't':
+ delsys = strtoul(optarg, NULL, 0);
+ break;
+ case 'c':
+ copt = 1;
+ strncpy(chanfile, optarg, sizeof(chanfile));
+ break;
+ case 'l':
+ if (lnb_decode(optarg, &lnb_type) < 0) {
+ bad_usage(argv[0], 1);
+ return -1;
+ }
+ break;
+ case 'x':
+ exit_after_tuning = 1;
+ break;
+ case 'i':
+ interactive = 1;
+ exit_after_tuning = 1;
+ }
+ }
+ lnb_type.low_val *= 1000; /* convert to kiloherz */
+ lnb_type.high_val *= 1000; /* convert to kiloherz */
+ lnb_type.switch_val *= 1000; /* convert to kiloherz */
+ if (optind < argc)
+ chan_name = argv[optind];
+ if (chan_name && chan_no) {
+ bad_usage(argv[0], 0);
+ return -1;
+ }
+ if (list_channels && (chan_name || chan_no)) {
+ bad_usage(argv[0], 0);
+ return -1;
+ }
+ if (!list_channels && !chan_name && !chan_no && !interactive) {
+ bad_usage(argv[0], 0);
+ return -1;
+ }
+
+ if (!copt) {
+ if (!(home = getenv("HOME"))) {
+ fprintf(stderr, "error: $HOME not set\n");
+ return TRUE;
+ }
+ snprintf(chanfile, sizeof(chanfile),
+ "%s/.szap/%i/%s", home, adapter, CHANNEL_FILE);
+ if (access(chanfile, R_OK))
+ snprintf(chanfile, sizeof(chanfile),
+ "%s/.szap/%s", home, CHANNEL_FILE);
+ }
+
+ printf("reading channels from file '%s'\n", chanfile);
+
+ if (rec_psi)
+ dvr=1;
+
+ if (!read_channels(chanfile, list_channels, chan_no, chan_name,
+ adapter, frontend, demux, dvr, rec_psi, bypass, delsys))
+
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/test/test.c b/test/test.c
index 6c9af51..2881a7a 100644
--- a/test/test.c
+++ b/test/test.c
@@ -1,4 +1,4 @@
-/*
+/*
* test.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -58,7 +58,7 @@ inline t2a(uint8_t c)
c=reverse[c]&0x7f;
if (c<0x20)
c=0x20;
-
+
return c;
}
@@ -68,16 +68,16 @@ void testpesfilter(void)
int i,j;
int len;
int fd=open("/dev/ost/demux1", O_RDWR);
- struct dmx_pes_filter_params pesFilterParams;
-
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_TS_TAP;
- pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ struct dmx_pes_filter_params pesFilterParams;
+
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
-
+
pesFilterParams.pid = 0x2c ;
if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
- printf("Could not set PES filter\n");
+ printf("Could not set PES filter\n");
close(fd);
return;
}
@@ -85,7 +85,7 @@ void testpesfilter(void)
/*
pesFilterParams.pid = 54;
if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
- printf("Could not set PES filter\n");
+ printf("Could not set PES filter\n");
close(fd);
return;
}
@@ -93,7 +93,7 @@ void testpesfilter(void)
pesFilterParams.pid = 55;
if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
- printf("Could not set PES filter\n");
+ printf("Could not set PES filter\n");
close(fd);
return;
}
@@ -103,7 +103,7 @@ void testpesfilter(void)
if (len>0) write(1, buf, len);
}
- do {
+ do {
read(fd, buf, 4);
if (htonl(*(uint32_t *)buf)!=0x00001bd)
continue;
@@ -112,10 +112,10 @@ void testpesfilter(void)
read(fd, buf+6, len);
fprintf(stderr,"read %d bytes PES\n", len);
write (1, buf, len+6);
-
+
id=buf[45];
fprintf(stderr,"id=%02x\n", id);
-
+
for (i=0; i<(len+6-46)/46; i++) {
for (j=6; j<46; j++) {
fprintf(stderr,"%c", t2a(buf[i*46+46+j]));
@@ -128,11 +128,11 @@ void testpesfilter(void)
/*
pesFilterParams.pid = 55;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
-
+
ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams);
close(fd);
*/
@@ -145,8 +145,8 @@ senf()
int len;
struct secCommand scmd;
struct secCmdSequence scmds;
- struct dmx_pes_filter_params pesFilterParams;
- struct dmx_sct_filter_params secFilterParams;
+ struct dmx_pes_filter_params pesFilterParams;
+ struct dmx_sct_filter_params secFilterParams;
FrontendParameters frp;
uint8_t buf[4096];
@@ -173,7 +173,7 @@ senf()
scmd.u.diseqc.cmd=0x38;
scmd.u.diseqc.numParams=1;
scmd.u.diseqc.params[0]=0xf0;
-
+
scmds.voltage=SEC_VOLTAGE_13;
scmds.miniCommand=SEC_MINI_NONE;
scmds.continuousTone=SEC_TONE_ON;
@@ -195,31 +195,31 @@ senf()
if (ret<0)
perror("DMX_SET_BUFFER_SIZE\n");
printf("Audio filter size OK\n");
- pesFilterParams.pid = 0x60;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_AUDIO;
+ pesFilterParams.pid = 0x60;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_AUDIO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
-
- if (ioctl(fd_demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
+
+ if (ioctl(fd_demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
printf("Audio filter OK\n");
-
- if (ioctl(fd_demux, DMX_SET_BUFFER_SIZE, 64*1024) < 0) return(1);
+
+ if (ioctl(fd_demux, DMX_SET_BUFFER_SIZE, 64*1024) < 0) return(1);
pesFilterParams.pid = 0xa2;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_VIDEO;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_VIDEO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demux, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
+ if (ioctl(fd_demux, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
printf("Video filter OK\n");
#endif
/*
pesFilterParams.pid = 56;
- pesFilterParams.input = DMX_IN_FRONTEND;
- pesFilterParams.output = DMX_OUT_DECODER;
- pesFilterParams.pes_type = DMX_PES_TELETEXT;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_tt, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
+ if (ioctl(fd_tt, DMX_SET_PES_FILTER, &pesFilterParams) < 0) return(1);
printf("TT filter OK\n");
*/
//while (1);
@@ -250,7 +250,7 @@ senf()
int32_t snr, str;
ioctl(fd_frontend, FE_READ_SNR, &snr);
ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &str);
-
+
printf("snr=%d, str=%d\n", snr, str);
}
*/
@@ -260,7 +260,7 @@ senf()
if (ioctl(fd_section, DMX_SET_FILTER, &secFilterParams) < 0) return;
//if (ioctl(fd_section2, DMX_SET_FILTER, &secFilterParams) < 0) return;
//close(fd_section2);
- //while (1)
+ //while (1)
{
len=read(fd_section, buf, 4096);
if (len>0) write(1, buf, len);
@@ -270,7 +270,7 @@ senf()
//if (len>0) write(1,buf,len);
//printf("read section with length %d\n", len);
}
-
+
}
main()
@@ -278,4 +278,3 @@ main()
//senf();
testpesfilter();
}
-
diff --git a/test/test_audio.c b/test/test_audio.c
index 0abb734..f7bfacc 100644
--- a/test/test_audio.c
+++ b/test/test_audio.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_audio.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -40,7 +40,7 @@ int audioStop(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_STOP,0) < 0)){
+ if ((ans = ioctl(fd,AUDIO_STOP,0)) < 0) {
perror("AUDIO STOP: ");
return -1;
}
@@ -52,7 +52,7 @@ int audioPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){
+ if ((ans = ioctl(fd,AUDIO_PLAY)) < 0) {
perror("AUDIO PLAY: ");
return -1;
}
@@ -65,7 +65,7 @@ int audioPause(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_PAUSE) < 0)){
+ if ((ans = ioctl(fd,AUDIO_PAUSE)) < 0) {
perror("AUDIO PAUSE: ");
return -1;
}
@@ -78,7 +78,7 @@ int audioContinue(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_CONTINUE) < 0)){
+ if ((ans = ioctl(fd,AUDIO_CONTINUE)) < 0) {
perror("AUDIO CONTINUE: ");
return -1;
}
@@ -90,7 +90,7 @@ int audioSelectSource(int fd, audio_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SELECT_SOURCE, source)) < 0) {
perror("AUDIO SELECT SOURCE: ");
return -1;
}
@@ -104,7 +104,7 @@ int audioSetMute(int fd, boolean state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_MUTE, state)) < 0) {
perror("AUDIO SET MUTE: ");
return -1;
}
@@ -116,7 +116,7 @@ int audioSetAVSync(int fd,boolean state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_AV_SYNC, state)) < 0) {
perror("AUDIO SET AV SYNC: ");
return -1;
}
@@ -128,8 +128,8 @@ int audioSetBypassMode(int fd,boolean mode)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_BYPASS_MODE, mode) < 0)){
- perror("AUDIO SET BYPASS MODE: ");
+ if ((ans = ioctl(fd,AUDIO_SET_BYPASS_MODE, mode)) < 0) {
+ printf("AUDIO SET BYPASS MODE not implemented?\n");
return -1;
}
@@ -141,7 +141,7 @@ int audioChannelSelect(int fd, audio_channel_select_t select)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_CHANNEL_SELECT, select) < 0)){
+ if ((ans = ioctl(fd,AUDIO_CHANNEL_SELECT, select)) < 0) {
perror("AUDIO CHANNEL SELECT: ");
return -1;
}
@@ -154,7 +154,7 @@ int audioGetStatus(int fd)
struct audio_status stat;
int ans;
- if ( (ans = ioctl(fd,AUDIO_GET_STATUS, &stat) < 0)){
+ if ((ans = ioctl(fd,AUDIO_GET_STATUS, &stat)) < 0) {
perror("AUDIO GET STATUS: ");
return -1;
}
@@ -179,7 +179,7 @@ int audioGetStatus(int fd)
printf("unknown (%d)\n",stat.play_state);
break;
}
-
+
printf(" Stream Source : ");
switch((int)stat.stream_source){
case AUDIO_SOURCE_DEMUX:
@@ -227,7 +227,7 @@ play_file_audio(int filefd, int fd)
int stopped = 0;
boolean mute = false;
boolean sync = false;
-
+
pfd[0].fd = STDIN_FILENO;
pfd[0].events = POLLIN;
@@ -257,7 +257,7 @@ play_file_audio(int filefd, int fd)
printf("playback stopped\n");
stopped = 1;
break;
-
+
case 'c':
audioContinue(fd);
printf("playback continued\n");
@@ -291,7 +291,7 @@ play_file_audio(int filefd, int fd)
break;
}
}
-
+
}
}
}
@@ -312,8 +312,8 @@ main(int argc, char **argv)
perror("File open:");
return -1;
}
-
- if((fd = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){
+
+ if ((fd = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){
perror("AUDIO DEVICE: ");
return -1;
}
@@ -321,7 +321,7 @@ main(int argc, char **argv)
audioSetMute(fd,mute);
- // audioSetBypassMode(fd,false); // not implemented
+ audioSetBypassMode(fd,false);
//audioContinue(fd);
audioSelectSource(fd,AUDIO_SOURCE_MEMORY);
audioPlay(fd);
@@ -334,7 +334,7 @@ main(int argc, char **argv)
//audioChannelSelect(fd,AUDIO_STEREO);
//audioSetAVSync(fd,sync);
audioGetStatus(fd);
-
+
play_file_audio(filefd,fd);
close(fd);
@@ -342,4 +342,3 @@ main(int argc, char **argv)
}
-
diff --git a/test/test_av.c b/test/test_av.c
index 5d77000..6c32848 100644
--- a/test/test_av.c
+++ b/test/test_av.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_av.c - Test for audio and video MPEG decoder API.
*
* Copyright (C) 2000 - 2002 convergence GmbH
@@ -30,6 +30,7 @@
#include <time.h>
#include <unistd.h>
+#include <linux/types.h>
#include <linux/dvb/audio.h>
#include <linux/dvb/video.h>
@@ -94,11 +95,11 @@ int audioSetMute(int fd, char *arg)
int audioSetAVSync(int fd, char *arg)
{
- int sync;
+ int _sync;
if (!arg)
return -1;
- sync = atoi(arg);
- if (ioctl(fd, AUDIO_SET_AV_SYNC, sync) == -1)
+ _sync = atoi(arg);
+ if (ioctl(fd, AUDIO_SET_AV_SYNC, _sync) == -1)
perror("AUDIO_SET_AV_SYNC");
return 0;
}
@@ -127,66 +128,66 @@ int audioChannelSelect(int fd, char *arg)
int audioGetStatus(int fd, char *arg)
{
- struct audio_status stat;
+ struct audio_status _stat;
if (arg)
return -1;
- if (ioctl(fd, AUDIO_GET_STATUS, &stat) == -1) {
+ if (ioctl(fd, AUDIO_GET_STATUS, &_stat) == -1) {
perror("AUDIO_GET_STATUS");
return 0;
}
printf("Audio Status:\n");
printf(" Sync State : %s\n",
- (stat.AV_sync_state ? "SYNC" : "NO SYNC"));
+ (_stat.AV_sync_state ? "SYNC" : "NO SYNC"));
printf(" Mute State : %s\n",
- (stat.mute_state ? "muted" : "not muted"));
+ (_stat.mute_state ? "muted" : "not muted"));
printf(" Play State : ");
- switch ((int)stat.play_state){
+ switch ((int)_stat.play_state){
case AUDIO_STOPPED:
- printf("STOPPED (%d)\n",stat.play_state);
+ printf("STOPPED (%d)\n",_stat.play_state);
break;
case AUDIO_PLAYING:
- printf("PLAYING (%d)\n",stat.play_state);
+ printf("PLAYING (%d)\n",_stat.play_state);
break;
case AUDIO_PAUSED:
- printf("PAUSED (%d)\n",stat.play_state);
+ printf("PAUSED (%d)\n",_stat.play_state);
break;
default:
- printf("unknown (%d)\n",stat.play_state);
+ printf("unknown (%d)\n",_stat.play_state);
break;
}
printf(" Stream Source : ");
- switch((int)stat.stream_source){
+ switch((int)_stat.stream_source){
case AUDIO_SOURCE_DEMUX:
- printf("DEMUX (%d)\n",stat.stream_source);
+ printf("DEMUX (%d)\n",_stat.stream_source);
break;
case AUDIO_SOURCE_MEMORY:
- printf("MEMORY (%d)\n",stat.stream_source);
+ printf("MEMORY (%d)\n",_stat.stream_source);
break;
default:
- printf("unknown (%d)\n",stat.stream_source);
+ printf("unknown (%d)\n",_stat.stream_source);
break;
}
printf(" Channel Select : ");
- switch((int)stat.channel_select){
+ switch((int)_stat.channel_select){
case AUDIO_STEREO:
- printf("Stereo (%d)\n",stat.channel_select);
+ printf("Stereo (%d)\n",_stat.channel_select);
break;
case AUDIO_MONO_LEFT:
- printf("Mono left(%d)\n",stat.channel_select);
+ printf("Mono left(%d)\n",_stat.channel_select);
break;
case AUDIO_MONO_RIGHT:
- printf("Mono right (%d)\n",stat.channel_select);
+ printf("Mono right (%d)\n",_stat.channel_select);
break;
default:
- printf("unknown (%d)\n",stat.channel_select);
+ printf("unknown (%d)\n",_stat.channel_select);
break;
}
printf(" Bypass Mode : %s\n",
- (stat.bypass_mode ? "ON" : "OFF"));
+ (_stat.bypass_mode ? "ON" : "OFF"));
return 0;
@@ -300,76 +301,76 @@ int videoSlowMotion(int fd, char *arg)
int videoGetStatus(int fd, char *arg)
{
- struct video_status stat;
+ struct video_status _stat;
if (arg)
return -1;
- if (ioctl(fd, VIDEO_GET_STATUS, &stat) == -1){
+ if (ioctl(fd, VIDEO_GET_STATUS, &_stat) == -1){
perror("VIDEO_GET_STATUS");
return 0;
}
printf("Video Status:\n");
printf(" Blank State : %s\n",
- (stat.video_blank ? "BLANK" : "STILL"));
+ (_stat.video_blank ? "BLANK" : "STILL"));
printf(" Play State : ");
- switch ((int)stat.play_state){
+ switch ((int)_stat.play_state){
case VIDEO_STOPPED:
- printf("STOPPED (%d)\n",stat.play_state);
+ printf("STOPPED (%d)\n",_stat.play_state);
break;
case VIDEO_PLAYING:
- printf("PLAYING (%d)\n",stat.play_state);
+ printf("PLAYING (%d)\n",_stat.play_state);
break;
case VIDEO_FREEZED:
- printf("FREEZED (%d)\n",stat.play_state);
+ printf("FREEZED (%d)\n",_stat.play_state);
break;
default:
- printf("unknown (%d)\n",stat.play_state);
+ printf("unknown (%d)\n",_stat.play_state);
break;
}
printf(" Stream Source : ");
- switch((int)stat.stream_source){
+ switch((int)_stat.stream_source){
case VIDEO_SOURCE_DEMUX:
- printf("DEMUX (%d)\n",stat.stream_source);
+ printf("DEMUX (%d)\n",_stat.stream_source);
break;
case VIDEO_SOURCE_MEMORY:
- printf("MEMORY (%d)\n",stat.stream_source);
+ printf("MEMORY (%d)\n",_stat.stream_source);
break;
default:
- printf("unknown (%d)\n",stat.stream_source);
+ printf("unknown (%d)\n",_stat.stream_source);
break;
}
printf(" Format (Aspect Ratio): ");
- switch((int)stat.video_format){
+ switch((int)_stat.video_format){
case VIDEO_FORMAT_4_3:
- printf("4:3 (%d)\n",stat.video_format);
+ printf("4:3 (%d)\n",_stat.video_format);
break;
case VIDEO_FORMAT_16_9:
- printf("16:9 (%d)\n",stat.video_format);
+ printf("16:9 (%d)\n",_stat.video_format);
break;
case VIDEO_FORMAT_221_1:
- printf("2.21:1 (%d)\n",stat.video_format);
+ printf("2.21:1 (%d)\n",_stat.video_format);
break;
default:
- printf("unknown (%d)\n",stat.video_format);
+ printf("unknown (%d)\n",_stat.video_format);
break;
}
printf(" Display Format : ");
- switch((int)stat.display_format){
+ switch((int)_stat.display_format){
case VIDEO_PAN_SCAN:
- printf("Pan&Scan (%d)\n",stat.display_format);
+ printf("Pan&Scan (%d)\n",_stat.display_format);
break;
case VIDEO_LETTER_BOX:
- printf("Letterbox (%d)\n",stat.display_format);
+ printf("Letterbox (%d)\n",_stat.display_format);
break;
case VIDEO_CENTER_CUT_OUT:
- printf("Center cutout (%d)\n",stat.display_format);
+ printf("Center cutout (%d)\n",_stat.display_format);
break;
default:
- printf("unknown (%d)\n",stat.display_format);
+ printf("unknown (%d)\n",_stat.display_format);
break;
}
return 0;
@@ -424,12 +425,12 @@ int videoStillPicture(int fd, char *arg)
sp.size = st.st_size;
printf("I-frame size: %d\n", sp.size);
- if(!sp.iFrame) {
+ if (!sp.iFrame) {
printf("No memory for I-Frame\n");
return 0;
}
- printf("read: %d bytes\n",read(sifd,sp.iFrame,sp.size));
+ printf("read: %d bytes\n", (int) read(sifd,sp.iFrame,sp.size));
if (ioctl(fd, VIDEO_STILLPICTURE, &sp) == -1)
perror("VIDEO_STILLPICTURE");
return 0;
@@ -555,11 +556,11 @@ int main(void)
printf("using audio device '%s'\n", audiodev);
printf("enter command or h + enter for help\n");
- if((vfd = open(videodev, O_RDWR | O_NONBLOCK)) < 0) {
+ if ((vfd = open(videodev, O_RDWR | O_NONBLOCK)) < 0) {
perror("open video device");
return 1;
}
- if((afd = open(audiodev, O_RDWR | O_NONBLOCK)) < 0) {
+ if ((afd = open(audiodev, O_RDWR | O_NONBLOCK)) < 0) {
perror("open audio device");
return 1;
}
@@ -571,4 +572,3 @@ int main(void)
close(afd);
return 0;
}
-
diff --git a/test/test_av_play.c b/test/test_av_play.c
index 293d6d8..b7ad867 100644
--- a/test/test_av_play.c
+++ b/test/test_av_play.c
@@ -19,27 +19,44 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * Thu Jun 24 09:18:44 CEST 2004
+ * Add scan_file_av() and copy_to_dvb() for AV
+ * filtering to be able to use AC3 audio streams
+ * Copyright (C) 2004 Werner Fink <werner@suse.de>
*/
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
#include <sys/ioctl.h>
#include <stdio.h>
+#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <netinet/in.h>
#include <fcntl.h>
#include <time.h>
+#include <termios.h>
#include <unistd.h>
+#include <errno.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <sys/poll.h>
+static char dolby;
+static char audio;
+static char black;
+static char volset;
+
static int audioPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){
+ if ((ans = ioctl(fd,AUDIO_PLAY)) < 0) {
perror("AUDIO PLAY: ");
return -1;
}
@@ -47,12 +64,11 @@ static int audioPlay(int fd)
return 0;
}
-
static int audioSelectSource(int fd, audio_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SELECT_SOURCE, source)) < 0) {
perror("AUDIO SELECT SOURCE: ");
return -1;
}
@@ -60,13 +76,11 @@ static int audioSelectSource(int fd, audio_stream_source_t source)
return 0;
}
-
-
static int audioSetMute(int fd, int state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_MUTE, state)) < 0) {
perror("AUDIO SET MUTE: ");
return -1;
}
@@ -78,7 +92,7 @@ static int audioSetAVSync(int fd, int state)
{
int ans;
- if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){
+ if ((ans = ioctl(fd,AUDIO_SET_AV_SYNC, state)) < 0) {
perror("AUDIO SET AV SYNC: ");
return -1;
}
@@ -86,11 +100,55 @@ static int audioSetAVSync(int fd, int state)
return 0;
}
+static int audioSetVolume(int fd, int level)
+{
+ int ans;
+ audio_mixer_t mix;
+
+ mix.volume_left = mix.volume_right = level;
+ if ((ans = ioctl(fd, AUDIO_SET_MIXER, &mix)) < 0) {
+ perror("AUDIO SET VOLUME: ");
+ return -1;
+ }
+ return 0;
+}
+
+static int audioStop(int fd)
+{
+ int ans;
+
+ if ((ans = ioctl(fd,AUDIO_STOP,0)) < 0) {
+ perror("AUDIO STOP: ");
+ return -1;
+ }
+ return 0;
+}
+
+static int deviceClear(int afd, int vfd)
+{
+ int ans;
+
+ if (vfd >= 0) {
+ if ((ans = ioctl(vfd, VIDEO_CLEAR_BUFFER, 0)) < 0) {
+ perror("VIDEO CLEAR BUFFER: ");
+ return -1;
+ }
+ }
+ if (afd >= 0) {
+ if ((ans = ioctl(afd, AUDIO_CLEAR_BUFFER, 0)) < 0) {
+ perror("AUDIO CLEAR BUFFER: ");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static int videoStop(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){
+ if ((ans = ioctl(fd,VIDEO_STOP,0)) < 0) {
perror("VIDEO STOP: ");
return -1;
}
@@ -102,7 +160,7 @@ static int videoPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){
+ if ((ans = ioctl(fd,VIDEO_PLAY)) < 0) {
perror("VIDEO PLAY: ");
return -1;
}
@@ -110,12 +168,11 @@ static int videoPlay(int fd)
return 0;
}
-
static int videoFreeze(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FREEZE)) < 0) {
perror("VIDEO FREEZE: ");
return -1;
}
@@ -123,12 +180,22 @@ static int videoFreeze(int fd)
return 0;
}
+static int videoBlank(int fd, int state)
+{
+ int ans;
+
+ if ((ans = ioctl(fd, VIDEO_SET_BLANK, state)) < 0) {
+ perror("VIDEO BLANK: ");
+ return -1;
+ }
+ return 0;
+}
static int videoContinue(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_CONTINUE)) < 0) {
perror("VIDEO CONTINUE: ");
return -1;
}
@@ -140,7 +207,7 @@ static int videoSelectSource(int fd, video_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SELECT_SOURCE, source)) < 0) {
perror("VIDEO SELECT SOURCE: ");
return -1;
}
@@ -153,7 +220,7 @@ static int videoFastForward(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes)) < 0) {
perror("VIDEO FAST FORWARD: ");
return -1;
}
@@ -165,7 +232,7 @@ static int videoSlowMotion(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SLOWMOTION, nframes)) < 0) {
perror("VIDEO SLOWMOTION: ");
return -1;
}
@@ -173,14 +240,11 @@ static int videoSlowMotion(int fd,int nframes)
return 0;
}
-#define BUFFY 32768
-#define NFD 2
-static void play_file_av(int filefd, int vfd, int afd)
+#define NFD 3
+static void copy_to_dvb(int vfd, int afd, int cfd, const uint8_t* ptr, const unsigned short len)
{
- char buf[BUFFY];
- int count;
- int written;
struct pollfd pfd[NFD];
+ unsigned short pos = 0;
int stopped = 0;
pfd[0].fd = STDIN_FILENO;
@@ -192,119 +256,399 @@ static void play_file_av(int filefd, int vfd, int afd)
pfd[2].fd = afd;
pfd[2].events = POLLOUT;
- videoSelectSource(vfd,VIDEO_SOURCE_MEMORY);
- audioSelectSource(afd,AUDIO_SOURCE_MEMORY);
-
- // FIXME: only seems to work if starting audio first!
- audioPlay(afd);
- videoPlay(vfd);
-
- count = read(filefd,buf,BUFFY);
- write(vfd,buf,count);
-
- while ( (count = read(filefd,buf,BUFFY)) >= 0 ){
- written = 0;
- while(written < count){
- if (poll(pfd,NFD,1)){
- if (pfd[1].revents & POLLOUT){
- written += write(vfd,buf+written,
- count-written);
+ while (pos < len) {
+ int ret;
+ if ((ret = poll(pfd,NFD,1)) > 0) {
+ if (pfd[1].revents & POLLOUT) {
+ int cnt = write(cfd, ptr + pos, len - pos);
+ if (cnt > 0)
+ pos += cnt;
+ else if (cnt < 0) {
+ if (errno != EAGAIN && errno != EINTR) {
+ perror("Write:");
+ exit(-1);
+ }
+ if (errno == EAGAIN)
+ usleep(1000);
+ continue;
}
- if (pfd[0].revents & POLLIN){
- int c = getchar();
- switch(c){
- case 'z':
+ }
+ if (pfd[0].revents & POLLIN) {
+ int c = getchar();
+ switch(c) {
+ case 'z':
+ if (audio && !black) {
+ audioSetMute(afd, 1);
+ } else {
videoFreeze(vfd);
- printf("playback frozen\n");
- stopped = 1;
- break;
-
- case 's':
+ }
+ deviceClear(afd, -1);
+ printf("playback frozen\n");
+ stopped = 1;
+ break;
+
+ case 's':
+ if (audio) {
+ audioStop(afd);
+ deviceClear(afd, -1);
+ } else {
videoStop(vfd);
- printf("playback stopped\n");
- stopped = 1;
- break;
-
- case 'c':
+ deviceClear(afd, vfd);
+ }
+ printf("playback stopped\n");
+ stopped = 1;
+ break;
+
+ case 'c':
+ if (audio && !black) {
+ audioSetAVSync(afd, 0);
+ deviceClear(afd, -1);
+ audioSetMute(afd, 0);
+ } else {
+ audioSetAVSync(afd, 1);
+ deviceClear(afd, vfd);
videoContinue(vfd);
- printf("playback continued\n");
- stopped = 0;
- break;
-
- case 'p':
- videoPlay(vfd);
+ }
+ printf("playback continued\n");
+ stopped = 0;
+ break;
+
+ case 'p':
+ if (audio) {
+ deviceClear(afd, -1);
+ audioSetAVSync(afd, 0);
audioPlay(afd);
- audioSetAVSync(afd, 1);
- audioSetMute(afd, 0);
- printf("playback started\n");
- stopped = 0;
- break;
-
- case 'f':
- audioSetAVSync(afd, 0);
+ } else {
+ deviceClear(afd, vfd);
+ audioSetAVSync(afd, 1);
+ audioPlay(afd);
+ videoPlay(vfd);
+ }
+ audioSetMute(afd, 0);
+ printf("playback started\n");
+ stopped = 0;
+ break;
+
+ case 'f':
+ audioSetAVSync(afd, 0);
+ if (!audio) {
audioSetMute(afd, 1);
videoFastForward(vfd,0);
- printf("fastforward\n");
- stopped = 0;
- break;
-
- case 'm':
- audioSetAVSync(afd, 0);
+ }
+ printf("fastforward\n");
+ stopped = 0;
+ break;
+
+ case 'm':
+ audioSetAVSync(afd, 0);
+ audioSetMute(afd, 1);
+ printf("mute\n");
+ stopped = 0;
+ break;
+
+ case 'u':
+ audioSetAVSync(afd, 1);
+ audioSetMute(afd, 0);
+ printf("unmute\n");
+ stopped = 0;
+ break;
+
+ case 'd':
+ if (dolby)
+ dolby = 0;
+ else
+ dolby++;
+ break;
+
+ case 'l':
+ audioSetAVSync(afd, 0);
+ if (!audio) {
audioSetMute(afd, 1);
videoSlowMotion(vfd,2);
- printf("slowmotion\n");
- stopped = 0;
- break;
+ }
+ printf("slowmotion\n");
+ stopped = 0;
+ break;
- case 'q':
- videoContinue(vfd);
- exit(0);
+ case 'q':
+ videoContinue(vfd);
+ exit(0);
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (ret < 0) {
+ if (errno != EAGAIN && errno != EINTR) {
+ perror("Write:");
+ exit(-1);
+ }
+ if (errno == EAGAIN)
+ usleep(1000);
+ }
+ }
+}
+
+static unsigned char play[6] = {0x00, 0x00, 0x01, 0xff, 0xff, 0xff};
+static unsigned char except[2];
+
+static int scan_file_av(int vfd, int afd, const unsigned char *buf, int buflen)
+{
+ const unsigned char *const start = buf;
+ const unsigned char *const end = buf + buflen;
+
+ static unsigned int magic = 0xffffffff;
+ static unsigned short count, len;
+ static int fdc = -1;
+ int m;
+
+ while (buf < end) {
+ if (count < 6) {
+ switch (count) {
+ case 0:
+ m = 0;
+ while ((magic & 0xffffff00) != 0x00000100) {
+ if (buf >= end) goto out;
+ magic = (magic << 8) | *buf++;
+ m++;
+ }
+ if (m > 4)
+ printf("Broken Frame found\n");
+ play[3] = (unsigned char)(magic & 0x000000ff);
+ switch (play[3]) {
+ case 0xE0 ... 0xEF:
+ fdc = vfd;
+ if (except[0] != play[3]) {
+ if (except[0] == 0)
+ except[0] = play[3];
+ else
+ fdc = -1;
+ }
+ if (audio)
+ fdc = -1;
+ break;
+ case 0xC0 ... 0xDF:
+ fdc = afd;
+ if (dolby) {
+ fdc = -1;
break;
}
+ if (except[1] != play[3]) {
+ if (except[1] == 0)
+ except[1] = play[3];
+ else
+ fdc = -1;
+ }
+ if (!volset) {
+ audioSetVolume(afd, 255);
+ volset = 1;
+ }
+ break;
+ case 0xBD:
+ /*
+ * TODO: sub filter to through out e.g. ub pictures
+ * in Private Streams 1 _and_ get sub audio header
+ * to set an except(ion) audio stream.
+ * The later one requires some changes within the VDR
+ * remux part! 2004/07/01 Werner
+ */
+ fdc = afd;
+ if (!dolby) {
+ fdc = -1;
+ break;
+ }
+ if (volset) {
+ audioSetVolume(afd, 0);
+ volset = 0;
+ }
+ break;
+ default:
+ fdc = -1;
+ break;
}
+ count = 4;
+ case 4:
+ if (buf >= end) goto out;
+ len = ((*buf) << 8);
+ play[4] = (*buf);
+ buf++;
+ count++;
+ case 5:
+ if (buf >= end) goto out;
+ len |= (*buf);
+ len += 6;
+ play[5] = (*buf);
+ buf++;
+ count++;
+ if (fdc != -1)
+ copy_to_dvb(vfd, afd, fdc, &play[0], count);
+ default:
+ break;
}
}
+
+ while (count < len) {
+ int rest = end - buf;
+ if (rest <= 0) goto out;
+
+ if (rest + count > len)
+ rest = len - count;
+
+ if (fdc != -1)
+ copy_to_dvb(vfd, afd, fdc, buf, rest);
+ count += rest;
+ buf += rest;
+ }
+
+ /* Reset for next scan */
+ magic = 0xffffffff;
+ count = len = 0;
+ fdc = -1;
+ play[3] = 0xff;
}
+out:
+ return buf - start;
+}
+
+#define BUFFY 32768
+static void play_file_av(int filefd, int vfd, int afd)
+{
+ unsigned char buf[BUFFY];
+ int count;
+
+ audioSetMute(afd, 1);
+ videoBlank(vfd, 1);
+ if (audio && !black) {
+ audioStop(afd);
+ deviceClear(afd, -1);
+ audioSetAVSync(afd, 0);
+ audioSelectSource(afd, AUDIO_SOURCE_MEMORY);
+ audioPlay(afd);
+ videoBlank(vfd, 0);
+ } else if (audio && black) {
+ deviceClear(afd, vfd);
+ videoBlank(vfd, 1);
+ audioSetAVSync(afd, 0);
+ audioSelectSource(afd, AUDIO_SOURCE_MEMORY);
+ videoSelectSource(vfd, VIDEO_SOURCE_MEMORY);
+ audioPlay(afd);
+ videoPlay(vfd);
+ } else {
+ deviceClear(afd, vfd);
+ audioSetAVSync(afd, 1);
+ audioSelectSource(afd, AUDIO_SOURCE_MEMORY);
+ videoSelectSource(vfd, VIDEO_SOURCE_MEMORY);
+ audioPlay(afd);
+ videoPlay(vfd);
+ videoBlank(vfd, 0);
+ }
+
+ if (dolby) {
+ audioSetVolume(afd, 0);
+ volset = 0;
+ } else {
+ audioSetVolume(afd, 255);
+ volset = 1;
+ }
+
+#ifndef __stub_posix_fadvise
+ posix_fadvise(filefd, 0, 0, POSIX_FADV_SEQUENTIAL);
+#endif
+
+ while ((count = read(filefd,buf,BUFFY)) > 0)
+ scan_file_av(vfd,afd,buf,count);
+}
+
+static struct termios term;
+
+static void restore(void)
+{
+ tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
int main(int argc, char **argv)
{
- int vfd, afd;
+ int vfd, afd, c;
int filefd;
- char *videodev = "/dev/dvb/adapter0/video0";
- char *audiodev = "/dev/dvb/adapter0/audio0";
+ const char *videodev = "/dev/dvb/adapter0/video0";
+ const char *audiodev = "/dev/dvb/adapter0/audio0";
+
+ if (((tcgetpgrp(STDIN_FILENO) == getpid()) || (getppid() != (pid_t)1))
+ && (tcgetattr(STDIN_FILENO, &term) == 0)) {
+ struct termios newterm;
+ memcpy(&newterm, &term, sizeof(struct termios));
+ newterm.c_iflag = 0;
+ newterm.c_lflag &= ~(ICANON | ECHO);
+ newterm.c_cc[VMIN] = 0;
+ newterm.c_cc[VTIME] = 0;
+ atexit(restore);
+ tcsetattr(STDIN_FILENO, TCSANOW, &newterm);
+ }
- if (argc < 2) {
- fprintf(stderr, "usage: test_av_play mpeg_A+V_PES_file\n");
- return 1;
+ opterr = 0;
+ while ((c = getopt(argc, argv, "+daA")) != -1) {
+ switch (c) {
+ case 'd':
+ dolby++;
+ break;
+ case 'a':
+ audio++;
+ break;
+ case 'A':
+ audio++;
+ black++;
+ break;
+ case '?':
+ fprintf(stderr, "usage: test_av_play [-d] [-a] [-A] mpeg_A+V_PES_file\n");
+ return 1;
+ default:
+ break;
+ }
}
+ argv += optind;
+ argc -= optind;
if (getenv("VIDEO"))
videodev = getenv("VIDEO");
if (getenv("AUDIO"))
- videodev = getenv("AUDIO");
+ audiodev = getenv("AUDIO");
printf("using video device '%s'\n", videodev);
printf("using audio device '%s'\n", audiodev);
- if ( (filefd = open(argv[1],O_RDONLY)) < 0){
+ putchar('\n');
+
+ printf("Freeze by pressing `z'\n");
+ printf("Stop by pressing `s'\n");
+ printf("Continue by pressing `c'\n");
+ printf("Start by pressing `p'\n");
+ printf("FastForward by pressing `f'\n");
+ printf("Mute by pressing `m'\n");
+ printf("UnMute by pressing `u'\n");
+ printf("MP2/AC3 by pressing `d'\n");
+ printf("SlowMotion by pressing `l'\n");
+ printf("Quit by pressing `q'\n");
+
+ putchar('\n');
+
+ errno = ENOENT;
+ if (!argv[0] || (filefd = open(argv[0], O_RDONLY)) < 0) {
perror("File open:");
return -1;
}
- if((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0){
+ if ((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0) {
perror("VIDEO DEVICE: ");
return -1;
}
- if((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0){
+ if ((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0) {
perror("AUDIO DEVICE: ");
return -1;
}
+
play_file_av(filefd, vfd, afd);
close(vfd);
close(afd);
close(filefd);
return 0;
-
-
}
-
diff --git a/test/test_dvr.c b/test/test_dvr.c
index 4cee62f..f61f872 100644
--- a/test/test_dvr.c
+++ b/test/test_dvr.c
@@ -82,7 +82,7 @@ static void process_data(int dvrfd, int tsfd)
fprintf(stderr, "got %d bytes (%llu total)\n", bytes, total_bytes);
}
-static int add_filter(unsigned int pid, const unsigned char* dmxdev)
+static int add_filter(unsigned int pid, const char* dmxdev)
{
int fd;
struct dmx_pes_filter_params f;
@@ -161,4 +161,3 @@ int main(int argc, char *argv[])
close(dvrfd);
return 0;
}
-
diff --git a/test/test_dvr_play.c b/test/test_dvr_play.c
index af963d9..7ab665f 100644
--- a/test/test_dvr_play.c
+++ b/test/test_dvr_play.c
@@ -141,4 +141,3 @@ int main(int argc, char **argv)
close(filefd);
return 0;
}
-
diff --git a/test/test_front.c b/test/test_front.c
index 1d08fc6..72acbb6 100644
--- a/test/test_front.c
+++ b/test/test_front.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_front.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -40,7 +40,7 @@ int OSTSelftest(int fd)
{
int ans;
- if ( (ans = ioctl(fd,OST_SELFTEST,0) < 0)){
+ if ((ans = ioctl(fd,OST_SELFTEST,0)) < 0) {
perror("OST SELF TEST: ");
return -1;
}
@@ -52,7 +52,7 @@ int OSTSetPowerState(int fd, uint32_t state)
{
int ans;
- if ( (ans = ioctl(fd,OST_SET_POWER_STATE,state) < 0)){
+ if ((ans = ioctl(fd,OST_SET_POWER_STATE,state)) < 0) {
perror("OST SET POWER STATE: ");
return -1;
}
@@ -64,7 +64,7 @@ int OSTGetPowerState(int fd, uint32_t *state)
{
int ans;
- if ( (ans = ioctl(fd,OST_GET_POWER_STATE,state) < 0)){
+ if ((ans = ioctl(fd,OST_GET_POWER_STATE,state)) < 0) {
perror("OST GET POWER STATE: ");
return -1;
}
@@ -95,7 +95,7 @@ int FEReadStatus(int fd)
int ans;
feStatus stat;
- if ( (ans = ioctl(fd,FE_READ_STATUS,&stat) < 0)){
+ if ((ans = ioctl(fd,FE_READ_STATUS,&stat)) < 0) {
perror("FE READ STATUS: ");
return -1;
}
@@ -116,7 +116,7 @@ int FEReadBER(int fd, uint32_t *ber)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_BER, ber) < 0)){
+ if ((ans = ioctl(fd,FE_READ_BER, ber)) < 0) {
perror("FE READ_BER: ");
return -1;
}
@@ -129,7 +129,7 @@ int FEReadSignalStrength(int fd, int32_t *strength)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_SIGNAL_STRENGTH, strength) < 0)){
+ if ((ans = ioctl(fd,FE_READ_SIGNAL_STRENGTH, strength)) < 0) {
perror("FE READ SIGNAL STRENGTH: ");
return -1;
}
@@ -142,7 +142,7 @@ int FEReadSNR(int fd, int32_t *snr)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_SNR, snr) < 0)){
+ if ((ans = ioctl(fd,FE_READ_SNR, snr)) < 0) {
perror("FE READ_SNR: ");
return -1;
}
@@ -156,7 +156,7 @@ int FEReadUncorrectedBlocks(int fd, uint32_t *ucb)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_UNCORRECTED_BLOCKS, ucb) < 0)){
+ if ((ans = ioctl(fd,FE_READ_UNCORRECTED_BLOCKS, ucb)) < 0) {
perror("FE READ UNCORRECTED BLOCKS: ");
return -1;
}
@@ -169,7 +169,7 @@ int FEGetNextFrequency(int fd, uint32_t *nfr)
{
int ans;
- if ( (ans = ioctl(fd,FE_GET_NEXT_FREQUENCY, nfr) < 0)){
+ if ((ans = ioctl(fd,FE_GET_NEXT_FREQUENCY, nfr)) < 0) {
perror("FE GET NEXT FREQUENCY: ");
return -1;
}
@@ -182,7 +182,7 @@ int FEGetNextSymbolRate(int fd, uint32_t *nsr)
{
int ans;
- if ( (ans = ioctl(fd,FE_GET_NEXT_SYMBOL_RATE, nsr) < 0)){
+ if ((ans = ioctl(fd,FE_GET_NEXT_SYMBOL_RATE, nsr)) < 0) {
perror("FE GET NEXT SYMBOL RATE: ");
return -1;
}
@@ -195,7 +195,7 @@ int QPSKTune(int fd, struct qpskParameters *param)
{
int ans;
- if ( (ans = ioctl(fd,QPSK_TUNE, param) < 0)){
+ if ((ans = ioctl(fd,QPSK_TUNE, param)) < 0) {
perror("QPSK TUNE: ");
return -1;
}
@@ -207,7 +207,7 @@ int QPSKGetEvent (int fd, struct qpskEvent *event)
{
int ans;
- if ( (ans = ioctl(fd,QPSK_GET_EVENT, event) < 0)){
+ if ((ans = ioctl(fd,QPSK_GET_EVENT, event)) < 0) {
perror("QPSK GET EVENT: ");
return -1;
}
@@ -219,7 +219,7 @@ int QPSKFEInfo (int fd, struct qpskFrontendInfo *info)
{
int ans;
- if ( (ans = ioctl(fd,QPSK_FE_INFO, info) < 0)){
+ if ((ans = ioctl(fd,QPSK_FE_INFO, info)) < 0) {
perror("QPSK FE INFO: ");
return -1;
}
@@ -238,7 +238,7 @@ int SecGetStatus (int fd, struct secStatus *state)
{
int ans;
- if ( (ans = ioctl(fd,SEC_GET_STATUS, state) < 0)){
+ if ((ans = ioctl(fd,SEC_GET_STATUS, state)) < 0) {
perror("QPSK GET EVENT: ");
return -1;
}
@@ -261,7 +261,7 @@ int SecGetStatus (int fd, struct secStatus *state)
break;
}
-
+
switch (state->selVolt){
case SEC_VOLTAGE_OFF:
printf("SEC VOLTAGE: OFF (%d)\n",state->selVolt);
@@ -299,11 +299,11 @@ main(int argc, char **argv)
struct qpskFrontendInfo info;
struct secStatus sec_state;
- if((fd = open("/dev/ost/qpskfe",O_RDWR)) < 0){
+ if ((fd = open("/dev/ost/qpskfe",O_RDWR)) < 0){
perror("FRONTEND DEVICE: ");
return -1;
}
- if((fd_sec = open("/dev/ost/sec",O_RDWR)) < 0){
+ if ((fd_sec = open("/dev/ost/sec",O_RDWR)) < 0){
perror("SEC DEVICE: ");
return -1;
}
@@ -325,4 +325,3 @@ main(int argc, char **argv)
close(fd);
close(fd_sec);
}
-
diff --git a/test/test_sec_ne.c b/test/test_sec_ne.c
index 9fcc8b3..350ac09 100644
--- a/test/test_sec_ne.c
+++ b/test/test_sec_ne.c
@@ -65,7 +65,7 @@ void process_section(int fd)
}
int set_filter(int fd, unsigned int pid, unsigned int tid,
- unsigned int tid_ext, unsigned int version_number)
+ unsigned int tid_ext, unsigned int _version_number)
{
struct dmx_sct_filter_params f;
unsigned long bufsz;
@@ -92,8 +92,8 @@ int set_filter(int fd, unsigned int pid, unsigned int tid,
f.filter.mask[1] = 0xff;
f.filter.mask[2] = 0xff;
}
- if (version_number < 0x20) {
- f.filter.filter[3] = (uint8_t) (version_number << 1);
+ if (_version_number < 0x20) {
+ f.filter.filter[3] = (uint8_t) (_version_number << 1);
f.filter.mask[3] = 0x3e;
f.filter.mode[3] = 0x3e;
}
@@ -162,4 +162,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_sections.c b/test/test_sections.c
index d567db0..7f32cc8 100644
--- a/test/test_sections.c
+++ b/test/test_sections.c
@@ -178,7 +178,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "0x%.2x ", mask[filter_idx]);
fprintf(stderr, "\n");
-
+
if ((dmxfd = open(dmxdev, O_RDWR)) < 0){
perror("open");
return 1;
@@ -194,4 +194,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_stc.c b/test/test_stc.c
index 89f141d..7afa817 100644
--- a/test/test_stc.c
+++ b/test/test_stc.c
@@ -71,4 +71,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_stillimage.c b/test/test_stillimage.c
index 264b2c4..358c0f1 100644
--- a/test/test_stillimage.c
+++ b/test/test_stillimage.c
@@ -6,7 +6,7 @@
*
* or more advanced using netpbm and mpeg2enc (not mpeg2encode) :
* $ cat image.jpg | jpegtopnm | pnmscale -xsize=704 -ysize=576 |\
- * ppmntsc --pal | ppmtoy4m -F 25:1 -A 4:3 |\
+ * ppmntsc --pal | ppmtoy4m -F 25:1 -A 4:3 -S 420mpeg2 |\
* mpeg2enc -f 7 -T 90 -F 3 -np -a 2 -o "image.mpg"
*
*/
@@ -21,6 +21,7 @@
#include <time.h>
#include <unistd.h>
+#include <linux/types.h>
#include <linux/dvb/video.h>
@@ -82,7 +83,7 @@ next_pic:
return -1;
}
- printf ("read: %d bytes\n", read(filefd, sp.iFrame, sp.size));
+ printf ("read: %d bytes\n", (int) read(filefd, sp.iFrame, sp.size));
close(filefd);
if ((ioctl(fd, VIDEO_STILLPICTURE, &sp) < 0)) {
@@ -99,5 +100,3 @@ next_pic:
return 0;
}
-
-
diff --git a/test/test_switch.c b/test/test_switch.c
index 7f80891..b2939ad 100644
--- a/test/test_switch.c
+++ b/test/test_switch.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_switch.c - Test program for new API
*
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
@@ -42,97 +42,97 @@ int fd_demuxv;
int fd_demuxtt;
struct dmx_sct_filter_params sctFilterParams;
-
+
struct secCommand scmd;
struct secCmdSequence scmds;
-struct dmx_pes_filter_params pesFilterParams;
-struct dmx_pes_filter_params pesFilterParamsV;
-struct dmx_pes_filter_params pesFilterParamsA;
-struct dmx_pes_filter_params pesFilterParamsTT;
+struct dmx_pes_filter_params pesFilterParams;
+struct dmx_pes_filter_params pesFilterParamsV;
+struct dmx_pes_filter_params pesFilterParamsA;
+struct dmx_pes_filter_params pesFilterParamsTT;
FrontendParameters frp;
int front_type;
-set_front(void)
+set_front(void)
{
fe_status_t stat = 0;
int i, freq;
uint32_t soff;
-
+
scmds.miniCommand = SEC_MINI_NONE;
scmds.numCommands = 1;
scmds.commands = &scmd;
-
+
soff = frp.u.qpsk.SymbolRate/16000;
if (ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds) < 0)
perror("setfront sec");
usleep(100000);
-
+
freq = frp.Frequency;
-
+
while(tune_it(&frp));
-}
+}
-set_diseqc_nb(int nr)
+set_diseqc_nb(int nr)
{
scmd.type=0;
scmd.u.diseqc.addr = 0x10;
scmd.u.diseqc.cmd = 0x38;
scmd.u.diseqc.numParams = 1;
- scmd.u.diseqc.params[0] = 0xF0 | ((nr * 4) & 0x0F) |
+ scmd.u.diseqc.params[0] = 0xF0 | ((nr * 4) & 0x0F) |
(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
}
-set_ttpid(ushort ttpid)
-{
+set_ttpid(ushort ttpid)
+{
if (ttpid==0 || ttpid==0xffff || ttpid==0x1fff) {
ioctl(fd_demuxtt, DMX_STOP, 0);
return;
}
pesFilterParamsTT.pid = ttpid;
- pesFilterParamsTT.input = DMX_IN_FRONTEND;
- pesFilterParamsTT.output = DMX_OUT_DECODER;
- pesFilterParamsTT.pes_type = DMX_PES_TELETEXT;
+ pesFilterParamsTT.input = DMX_IN_FRONTEND;
+ pesFilterParamsTT.output = DMX_OUT_DECODER;
+ pesFilterParamsTT.pes_type = DMX_PES_TELETEXT;
pesFilterParamsTT.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER,
&pesFilterParamsTT) < 0) {
printf("PID=%04x\n", ttpid);
perror("set_ttpid");
}
}
-set_vpid(ushort vpid)
-{
+set_vpid(ushort vpid)
+{
if (vpid==0 || vpid==0xffff || vpid==0x1fff) {
ioctl(fd_demuxv, DMX_STOP, 0);
return;
}
pesFilterParamsV.pid = vpid;
- pesFilterParamsV.input = DMX_IN_FRONTEND;
- pesFilterParamsV.output = DMX_OUT_DECODER;
- pesFilterParamsV.pes_type = DMX_PES_VIDEO;
+ pesFilterParamsV.input = DMX_IN_FRONTEND;
+ pesFilterParamsV.output = DMX_OUT_DECODER;
+ pesFilterParamsV.pes_type = DMX_PES_VIDEO;
pesFilterParamsV.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxv, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxv, DMX_SET_PES_FILTER,
&pesFilterParamsV) < 0)
perror("set_vpid");
}
-set_apid(ushort apid)
-{
+set_apid(ushort apid)
+{
if (apid==0 || apid==0xffff || apid==0x1fff) {
ioctl(fd_demuxa, DMX_STOP, apid);
return;
}
pesFilterParamsA.pid = apid;
- pesFilterParamsA.input = DMX_IN_FRONTEND;
- pesFilterParamsA.output = DMX_OUT_DECODER;
- pesFilterParamsA.pes_type = DMX_PES_AUDIO;
+ pesFilterParamsA.input = DMX_IN_FRONTEND;
+ pesFilterParamsA.output = DMX_OUT_DECODER;
+ pesFilterParamsA.pes_type = DMX_PES_AUDIO;
pesFilterParamsA.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
&pesFilterParamsA) < 0)
perror("set_apid");
}
@@ -156,7 +156,7 @@ int tune_it(FrontendParameters *frp)
if (poll(pfd,1,3000)){
if (pfd[0].revents & POLLIN){
printf("Getting QPSK event\n");
- if ( ioctl(fd_frontend, FE_GET_EVENT, &event)
+ if ( ioctl(fd_frontend, FE_GET_EVENT, &event)
== -EOVERFLOW){
perror("qpsk get event");
@@ -170,7 +170,7 @@ int tune_it(FrontendParameters *frp)
case FE_FAILURE_EV:
printf("failure event\n");
return -1;
-
+
case FE_COMPLETION_EV:
printf("completion event\n");
}
@@ -179,7 +179,7 @@ int tune_it(FrontendParameters *frp)
return 0;
}
-set_tp(uint *freq, int ttk, int pol, uint srate, int dis)
+set_tp(uint *freq, int ttk, int pol, uint srate, int dis)
{
if (*freq < 11700000) {
frp.Frequency = (*freq - 9750000);
@@ -195,22 +195,22 @@ set_tp(uint *freq, int ttk, int pol, uint srate, int dis)
frp.u.qpsk.FEC_inner = 0;
}
-get_front(void)
+get_front(void)
{
set_vpid(0);
set_apid(0);
set_ttpid(0);
- scmds.voltage = SEC_VOLTAGE_18;
+ scmds.voltage = SEC_VOLTAGE_18;
scmds.miniCommand = SEC_MINI_NONE;
scmds.continuousTone = SEC_TONE_OFF;
scmds.numCommands=1;
scmds.commands=&scmd;
-
+
frp.Frequency=(12073000-10600000);
frp.u.qpsk.SymbolRate=25378000;
frp.u.qpsk.FEC_inner=(fe_code_rate_t)5;
-}
-
+}
+
void get_sect(int fd)
{
@@ -219,10 +219,10 @@ void get_sect(int fd)
uint16_t cpid = 0;
uint16_t length;
struct pollfd pfd;
-
+
pfd.fd = fd;
pfd.events = POLLIN;
-
+
while (1){
if (poll(&pfd, 1, 5000) != POLLIN) {
printf("not found\n");
@@ -232,7 +232,7 @@ void get_sect(int fd)
length = (sec[1]& 0x0F)<<8;
length |= (sec[2]& 0xFF);
-
+
for (i= 0; i < length+3; i++) {
printf("0x%02x ",sec[i]);
@@ -248,7 +248,7 @@ int FEReadStatus(int fd, fe_status_t *stat)
{
int ans;
- if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){
+ if ((ans = ioctl(fd,FE_READ_STATUS,stat)) < 0) {
perror("FE READ STATUS: ");
return -1;
}
@@ -268,7 +268,7 @@ int FEReadStatus(int fd, fe_status_t *stat)
int has_signal()
{
fe_status_t stat;
-
+
FEReadStatus(fd_frontend, &stat);
if (stat & FE_HAS_SIGNAL)
return 1;
@@ -304,7 +304,7 @@ main()
scmds.commands=&scmd;
frp.Frequency = (12073000 - 10600000);
// frp.Frequency = (11975000 - 10600000);
- scmds.continuousTone = SEC_TONE_ON;
+ scmds.continuousTone = SEC_TONE_ON;
frp.u.qpsk.SymbolRate = 25378000;
// frp.u.qpsk.SymbolRate = 27500000;
// frp.u.qpsk.FEC_inner = FEC_AUTO;
@@ -313,7 +313,7 @@ main()
scmd.u.diseqc.addr = 0x10;
scmd.u.diseqc.cmd = 0x38;
scmd.u.diseqc.numParams = 1;
- scmd.u.diseqc.params[0] = 0xF0 | ((3 * 4) & 0x0F) |
+ scmd.u.diseqc.params[0] = 0xF0 | ((3 * 4) & 0x0F) |
(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
@@ -324,7 +324,7 @@ main()
/*
- if ((fd_demuxa=open("/dev/ost/demux", O_RDWR|O_NONBLOCK))
+ if ((fd_demuxa=open("/dev/ost/demux", O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
@@ -336,18 +336,18 @@ main()
sctFilterParams.timeout = 0;
sctFilterParams.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxa, DMX_SET_FILTER, &sctFilterParams) < 0)
+ if (ioctl(fd_demuxa, DMX_SET_FILTER, &sctFilterParams) < 0)
perror("DMX SET FILTER:");
get_sect(fd_demuxa);
*/
pesFilterParamsA.pid = 0x1fff;
- pesFilterParamsA.input = DMX_IN_FRONTEND;
- pesFilterParamsA.output = DMX_OUT_TS_TAP;
- pesFilterParamsA.pes_type = DMX_PES_OTHER;
+ pesFilterParamsA.input = DMX_IN_FRONTEND;
+ pesFilterParamsA.output = DMX_OUT_TS_TAP;
+ pesFilterParamsA.pes_type = DMX_PES_OTHER;
pesFilterParamsA.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
+ if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,
&pesFilterParamsA) < 0)
perror("set_apid");
diff --git a/test/test_tt.c b/test/test_tt.c
index 6511f39..da288d3 100644
--- a/test/test_tt.c
+++ b/test/test_tt.c
@@ -202,4 +202,3 @@ int main(int argc, char *argv[])
close(dmxfd);
return 0;
}
-
diff --git a/test/test_vevent.c b/test/test_vevent.c
index f61143e..bfd0369 100644
--- a/test/test_vevent.c
+++ b/test/test_vevent.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_vevent.c - Test VIDEO_GET_EVENT and poll(9 for video events
*
* Copyright (C) 2003 convergence GmbH
@@ -29,6 +29,7 @@
#include <time.h>
#include <unistd.h>
+#include <linux/types.h>
#include <linux/dvb/video.h>
@@ -73,7 +74,7 @@ int main(void)
printf("using video device '%s'\n", videodev);
- if((vfd = open(videodev, O_RDONLY | O_NONBLOCK)) < 0) {
+ if ((vfd = open(videodev, O_RDONLY | O_NONBLOCK)) < 0) {
perror("open video device");
return 1;
}
@@ -122,4 +123,3 @@ int main(void)
close(vfd);
return 0;
}
-
diff --git a/test/test_video.c b/test/test_video.c
index 09c2be1..ac66050 100644
--- a/test/test_video.c
+++ b/test/test_video.c
@@ -1,4 +1,4 @@
-/*
+/*
* test_video.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
@@ -40,7 +40,7 @@ int videoStop(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){
+ if ((ans = ioctl(fd,VIDEO_STOP,0)) < 0) {
perror("VIDEO STOP: ");
return -1;
}
@@ -52,7 +52,7 @@ int videoPlay(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){
+ if ((ans = ioctl(fd,VIDEO_PLAY)) < 0) {
perror("VIDEO PLAY: ");
return -1;
}
@@ -65,7 +65,7 @@ int videoFreeze(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FREEZE)) < 0) {
perror("VIDEO FREEZE: ");
return -1;
}
@@ -78,7 +78,7 @@ int videoContinue(int fd)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){
+ if ((ans = ioctl(fd,VIDEO_CONTINUE)) < 0) {
perror("VIDEO CONTINUE: ");
return -1;
}
@@ -90,7 +90,7 @@ int videoSelectSource(int fd, video_stream_source_t source)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SELECT_SOURCE, source)) < 0) {
perror("VIDEO SELECT SOURCE: ");
return -1;
}
@@ -104,7 +104,7 @@ int videoSetBlank(int fd, boolean state)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SET_BLANK, state) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SET_BLANK, state)) < 0) {
perror("VIDEO SET BLANK: ");
return -1;
}
@@ -116,7 +116,7 @@ int videoFastForward(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes)) < 0) {
perror("VIDEO FAST FORWARD: ");
return -1;
}
@@ -128,7 +128,7 @@ int videoSlowMotion(int fd,int nframes)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){
+ if ((ans = ioctl(fd,VIDEO_SLOWMOTION, nframes)) < 0) {
perror("VIDEO SLOWMOTION: ");
return -1;
}
@@ -141,7 +141,7 @@ int videoGetStatus(int fd)
struct video_status stat;
int ans;
- if ( (ans = ioctl(fd,VIDEO_GET_STATUS, &stat) < 0)){
+ if ((ans = ioctl(fd,VIDEO_GET_STATUS, &stat)) < 0) {
perror("VIDEO GET STATUS: ");
return -1;
}
@@ -164,7 +164,7 @@ int videoGetStatus(int fd)
printf("unknown (%d)\n",stat.play_state);
break;
}
-
+
printf(" Stream Source : ");
switch((int)stat.stream_source){
case VIDEO_SOURCE_DEMUX:
@@ -213,7 +213,7 @@ int videoStillPicture(int fd, struct video_still_picture *sp)
{
int ans;
- if ( (ans = ioctl(fd,VIDEO_STILLPICTURE, sp) < 0)){
+ if ((ans = ioctl(fd,VIDEO_STILLPICTURE, sp)) < 0) {
perror("VIDEO STILLPICTURE: ");
return -1;
}
@@ -234,17 +234,17 @@ void play_file_video(int filefd, int fd)
pfd[0].fd = STDIN_FILENO;
pfd[0].events = POLLIN;
-
+
pfd[1].fd = fd;
pfd[1].events = POLLOUT;
-
+
videoSelectSource(fd,VIDEO_SOURCE_MEMORY);
videoPlay(fd);
-
-
+
+
count = read(filefd,buf,BUFFY);
write(fd,buf,count);
-
+
while ( (count = read(filefd,buf,BUFFY)) >= 0 ){
written = 0;
while(written < count){
@@ -267,7 +267,7 @@ void play_file_video(int filefd, int fd)
printf("playback stopped\n");
stopped = 1;
break;
-
+
case 'c':
videoContinue(fd);
printf("playback continued\n");
@@ -298,7 +298,7 @@ void play_file_video(int filefd, int fd)
break;
}
}
-
+
}
}
}
@@ -310,12 +310,12 @@ void load_iframe(int filefd, int fd)
struct video_still_picture sp;
fstat(filefd, &st);
-
+
sp.iFrame = (char *) malloc(st.st_size);
sp.size = st.st_size;
printf("I-frame size: %d\n", sp.size);
-
- if(!sp.iFrame) {
+
+ if (!sp.iFrame) {
printf("No memory for I-Frame\n");
return;
}
@@ -338,12 +338,12 @@ main(int argc, char **argv)
perror("File open:");
return -1;
}
- if((fd = open("/dev/ost/video1",O_RDWR|O_NONBLOCK)) < 0){
+ if ((fd = open("/dev/ost/video1",O_RDWR|O_NONBLOCK)) < 0){
perror("VIDEO DEVICE: ");
return -1;
}
-
-
+
+
// videoSetBlank(fd,false);
@@ -365,4 +365,3 @@ main(int argc, char **argv)
}
-
diff --git a/test/video.c b/test/video.c
index ea9e4a2..fae421e 100644
--- a/test/video.c
+++ b/test/video.c
@@ -1,13 +1,14 @@
- /**
- * A tiny video watching application, just starts capturing /dev/video
- * into /dev/fb0.
- * Be shure to have >8Bit/pixel color resolution and r/w access for
- * /dev/video0, /dev/fb0 and /dev/tty0 to let this work...
- *
- * compile with
- *
- * $ gcc -g -Wall -O2 -o video video.c -I../../ost/include
- */
+#define USAGE \
+"\n" \
+"\n A tiny video watching application, just starts capturing /dev/video" \
+"\n into /dev/fb0." \
+"\n Be shure to have >8Bit/pixel color resolution and r/w access for " \
+"\n /dev/video0, /dev/fb0 and /dev/tty0 to let this work..." \
+"\n" \
+"\n compile with" \
+"\n" \
+"\n $ gcc -g -Wall -O2 -o video video.c -I../../ost/include" \
+"\n"
#include <sys/mman.h>
#include <sys/ioctl.h>
@@ -55,7 +56,7 @@ int init_fb (void)
}
write( vt_fd, blankoff_str, strlen(blankoff_str) );
-
+
if (ioctl (fd, FBIOGET_VSCREENINFO, &fb_var) < 0) {
perror("Could not get variable screen information (fb_var)\n");
return 1;
@@ -77,14 +78,14 @@ int init_video (int stop)
struct video_capability vcap;
if ((fd = open (video_devname, O_RDWR)) < 0) {
- fprintf (stderr,
+ fprintf (stderr,
"%s: Could not open %s, please check permissions\n",
__FUNCTION__, video_devname);
return -1;
}
ioctl(fd, VIDIOCGCAP, &vcap);
-
+
if (ioctl(fd, VIDIOCCAPTURE, &zero) < 0) {
perror("Could not stop capturing (VIDIOCCAPTURE failed)\n");
return -2;
@@ -92,7 +93,7 @@ int init_video (int stop)
if (stop)
return 0;
-
+
{
struct video_buffer b;
b.base = (void*) fb_fix.smem_start;
@@ -105,7 +106,7 @@ int init_video (int stop)
return -3;
}
}
-
+
{
struct video_picture p;
if (ioctl(fd, VIDIOCGPICT, &p) < 0) {
@@ -131,7 +132,7 @@ int init_video (int stop)
return -5;
}
}
-
+
{
struct video_window win;
win.width = min((__u32) vcap.maxwidth, fb_var.xres);
@@ -147,14 +148,14 @@ int init_video (int stop)
return -6;
}
}
-
+
if (ioctl(fd, VIDIOCCAPTURE, &one) < 0) {
perror("Could not start capturing (VIDIOCCAPTURE failed)\n");
return -7;
}
-
+
close (fd);
-
+
return 0;
}
@@ -173,10 +174,9 @@ int main (int argc, char **argv)
video_devname = argv[1];
if (argc != 1 && argc != 2 && !(argc == 3 && stop)) {
- fprintf (stderr, "usage: %s <devname> <stop>\n", argv[0]);
+ fprintf(stderr, "usage: %s <devname> <stop>\n" USAGE, argv[0]);
exit (-1);
}
return init_video (stop);
}
-