Thread: [Redbutton-devel] SF.net SVN: redbutton: [32]
Brought to you by:
skilvington
|
From: <ski...@us...> - 2006-04-03 10:22:53
|
Revision: 32 Author: skilvington Date: 2006-04-03 03:22:45 -0700 (Mon, 03 Apr 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=32&view=rev Log Message: ----------- import redbutton.sourceforge.net index.html Added Paths: ----------- www/ www/index.html Added: www/index.html =================================================================== --- www/index.html (rev 0) +++ www/index.html 2006-04-03 10:22:45 UTC (rev 32) @@ -0,0 +1,145 @@ +<HTML> +<HEAD> +<TITLE>RedButton MHEG Engine</TITLE> +</HEAD> +<BODY> +<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=158629&type=2" width="125" height="37" border="0" alt="SourceForge.net Logo" /></a> +<H1>RedButton MHEG Engine</H1> +RedButton allows you to use the interactive MHEG applications broadcast with DVB digital TV services. +MHEG replaces the text only services available with analogue TV. +<P> +RedButton consists of two parts. The first, rb-download, allows MHEG data to be downloaded from a DVB service. The second, rb-browser, allows the downloaded MHEG applications to be displayed. +<P> +The source for both is released under the GPL and can be +<A HREF="http://sourceforge.net/project/showfiles.php?group_id=158629">downloaded here.</A> +<P> +Just un-tar them and type 'make'. +<P> +You can browser the latest version of the source +<A HREF="http://svn.sourceforge.net/redbutton/">here.</A> +You can download the latest source code with the following Subversion command: +<PRE> +svn checkout https://svn.sourceforge.net/svnroot/redbutton/ +</PRE> +<P> +You can subscribe to the development mailing list +<A HREF="http://lists.sourceforge.net/lists/listinfo/redbutton-devel">here.</A> +<H2>rb-download</H2> +Usage: +<PRE> +rb-download [-d <demux_device>] [-b <base_dir>] [-t <timeout>] [-c <carousel_id>] [<service_id>] +</PRE> +Download the DVB Object Carousel for the given channel onto the local hard disc. +<P> +The default demux device is /dev/dvb/adapter0/demux0. +<P> +If no directory is given with -b, files will be stored under the current directory. +Note that <base_dir> must already exist and be writeable. +<P> +The default timeout is 10 seconds. +If no DSM-CC data is found after this time, it is assumed none is being broadcast. +<P> +The <carousel_id> will normally be read from the PMT, but you can use the -c option to explicitly choose a carousel. +<P> +If no <service_id> is given, a list of possible channels (and their <service_id>) is printed. +These will be the channels available on the MUX your DVB card is currently tuned to. Use dvbtune or equivalent to tune your card. +<P> +The file structure stored under <base_dir> will be: +<PRE> +./services/<service_id> +</PRE> +this is a symlink to the root of the carousel for the given service. +<P> +The actual carousel files and directories are stored under: +<PRE> +./carousels/<PID>/<CID>/ +</PRE> +where <PID> is the PID the carousel was downloaded from +and <CID> is the Carousel ID. +<P> +Just leave it running and any updated files will be downloaded as they are broadcast. +<H2>Notes</H2> +I've compiled and run it under Gentoo and Mandr{ake,iva} Linux on x86, but it should work on any (big- or little-endian) Linux distro. +<P> +It only implements a subset of the whole DSM-CC specs. +However, it is enough to download everything that is currently being broadcast +on the 'Freeview' DVB-T channels in the UK. +<P> +Once the data is downloaded, you can use rb-browser (see below) to view it. +<H2>rb-browser</H2> +Usage: +<PRE> +rb-browser [-v] [-f] [-k <keymap_config_file>] [-t <timeout>] <service_gateway_dir> +</PRE> +Display the MHEG apps downloaded with rb-download. +The <service_gateway_dir> should be one of the entries in the services directory, eg +<PRE> +rb-browser services/4165 +</PRE> +It will display the app in a window, use -f for full screen mode. +<P> +The -v flag enables verbose/debug mode. +<P> +The -t flag determines how long (in seconds) it will poll for missing files before passing an error to the MHEG application. +The default is 10 seconds. +<P> +Use the -k option to load a keymap (keymap config files can be generated with the rb-keymap command). +The default keys to navigate around the apps are: +<P> +<TABLE border="1" cellpadding="5"> +<TR><TH>Key</TH><TH>Function</TH></TR> +<TR align="center"><TD>Cursor Keys</TD><TD>Up/Down/Left/Right</TD></TR> +<TR align="center"><TD>0 - 9</TD><TD>0 - 9</TD></TR> +<TR align="center"><TD>r</TD><TD>Red</TD></TR> +<TR align="center"><TD>g</TD><TD>Green</TD></TR> +<TR align="center"><TD>b</TD><TD>Blue</TD></TR> +<TR align="center"><TD>y</TD><TD>Yellow</TD></TR> +<TR align="center"><TD>Return</TD><TD>OK/Select</TD></TR> +<TR align="center"><TD>Escape</TD><TD>Cancel</TD></TR> +<TR align="center"><TD>t</TD><TD>Text</TD></TR> +</TABLE> +<P> +You will need the "expat" XML parsing library and the xsltproc XML stylesheet processor that comes with "libxslt" to compile it. +On Gentoo, you can just: +<PRE> +emerge expat libxslt +</PRE> +If the compile fails with errors about missing .c files, expat is not installed. +If the compile fails with errors about function names ending in "_dup" being missing, libxslt is not installed. +<P> +To run it you need an X server that supports the Xrender extension and you need to have libpng, libmpeg2 and freetype2 installed. +<H2>Notes</H2> +It's not finished yet! +It'll only draw text, rectangles and PNG bitmaps at the moment and some of the ElementaryActions are not yet implemented. +However, it is enough to be usable. +The main things missing are video and audio streams, at the moment it'll just draw a green box where any video should be. +<P> +It will only display apps that conform to the UK MHEG Profile (available from +<A href="http://www.dtg.org.uk/">www.dtg.org.uk</A>). +<P> +If you get a blank screen when it starts, try pressing 'r' (for BBC) or 't' (for ITV/C4) to activate +any MHEG app that may be waiting for you to do something. +<P> +The default font for the UK MHEG Profile is Tiresias Screenfont which was +developed with the RNIB to be readable on TV screens. +You can download this font as part of the DigiTV iTuner package from +<A href="http://www.nebula-electronics.com/">Nebula Electronics</A>. +Extract the file called tt7268m_802.ttf and add it to your X Windows fonts. +The easiest way is to install DigiTV iTuner on a Windows box and then copy the +C:\Windows\Fonts\tt7268m_802.ttf file onto your Linux box. +To install new X fonts in KDE, open the Control Centre application, +go to the System Administration section and select Font Installer. +<P> +Alternatively, if you know someone in Australia, ABC is currently broadcasting +Tiresias.pfr as part of their TV guide application. +You can download it with rb-download. +The Australian applications are MHP, not MHEG, so you should probably look at +<A href="http://www.openmhp.org/">www.openmhp.org</A> for something to display them. +<P> +If the Tiresias Screenfont is not available, rb-browser uses whatever scalable font Xft returns for "sans" instead. +Note that this font will have different metrics and so may not fit into the spaces in the MHEG apps designed for Tiresias. +<H2>Contact Details</H2> +I can be contacted here: s.kilvington at eris dot qinetiq com. +</BODY> +</HTML> + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-11-07 16:49:29
|
Revision: 153
http://svn.sourceforge.net/redbutton/?rev=153&view=rev
Author: skilvington
Date: 2006-11-07 08:49:22 -0800 (Tue, 07 Nov 2006)
Log Message:
-----------
add install target to Makefiles
Modified Paths:
--------------
redbutton-browser/trunk/Makefile
redbutton-download/trunk/Makefile
Modified: redbutton-browser/trunk/Makefile
===================================================================
--- redbutton-browser/trunk/Makefile 2006-11-07 16:40:18 UTC (rev 152)
+++ redbutton-browser/trunk/Makefile 2006-11-07 16:49:22 UTC (rev 153)
@@ -3,6 +3,8 @@
# gprof profiling
#CFLAGS=-Wall -O2 -pg
+DESTDIR=/usr/local
+
DEFS=-D_REENTRANT -D_GNU_SOURCE
# safe_malloc debugging
#DEFS=-DDEBUG_ALLOC -D_REENTRANT -D_GNU_SOURCE
@@ -115,6 +117,10 @@
berdecode: berdecode.c
${CC} ${CFLAGS} ${DEFS} -o berdecode berdecode.c
+install: rb-browser rb-keymap
+ install -m 755 rb-browser ${DESTDIR}/bin
+ install -m 755 rb-keymap ${DESTDIR}/bin
+
clean:
rm -f rb-browser rb-keymap xsd2c dertest dertest-mheg.[ch] berdecode *.o ISO13522-MHEG-5.[ch] clone.[ch] rtti.h gmon.out core
Modified: redbutton-download/trunk/Makefile
===================================================================
--- redbutton-download/trunk/Makefile 2006-11-07 16:40:18 UTC (rev 152)
+++ redbutton-download/trunk/Makefile 2006-11-07 16:49:22 UTC (rev 153)
@@ -1,6 +1,8 @@
CC=gcc
CFLAGS=-Wall -O
+DESTDIR=/usr/local
+
OBJS= rb-download.o \
list.o \
findmheg.o \
@@ -26,6 +28,9 @@
.c.o:
${CC} ${CFLAGS} -c $<
+install: rb-download
+ install -m 755 rb-download ${DESTDIR}/bin
+
clean:
rm -f rb-download *.o core
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-22 10:31:47
|
Revision: 185
http://svn.sourceforge.net/redbutton/?rev=185&view=rev
Author: skilvington
Date: 2007-01-22 02:31:43 -0800 (Mon, 22 Jan 2007)
Log Message:
-----------
use ~/.tzap/channels.conf as default channels.conf file
Modified Paths:
--------------
redbutton-download/trunk/channels.c
redbutton-download/trunk/rb-download.c
www/index.html
Modified: redbutton-download/trunk/channels.c
===================================================================
--- redbutton-download/trunk/channels.c 2007-01-18 22:26:22 UTC (rev 184)
+++ redbutton-download/trunk/channels.c 2007-01-22 10:31:43 UTC (rev 185)
@@ -41,7 +41,7 @@
/*
* if filename is NULL, it searches for:
- * ~/channels.conf
+ * ~/.tzap/channels.conf
* /etc/channels.conf
*/
@@ -58,7 +58,7 @@
{
if((home = getenv("HOME")) != NULL)
{
- snprintf(pathname, sizeof(pathname), "%s/channels.conf", home);
+ snprintf(pathname, sizeof(pathname), "%s/.tzap/channels.conf", home);
verbose("Trying to open %s", pathname);
_channels = fopen(pathname, "r");
}
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2007-01-18 22:26:22 UTC (rev 184)
+++ redbutton-download/trunk/rb-download.c 2007-01-22 10:31:43 UTC (rev 185)
@@ -18,7 +18,7 @@
* rb-download needs a "channels.conf" file which gives tuning parameters for service_id's
* channels.conf files can be generated by the "scan" utility in the dvb-apps package at www.linuxtv.org
* if not specified with -f, rb-download will search for:
- * ~/channels.conf
+ * ~/.tzap/channels.conf
* /etc/channels.conf
*
* rb-download listens on the network for commands from a remote rb-browser
Modified: www/index.html
===================================================================
--- www/index.html 2007-01-18 22:26:22 UTC (rev 184)
+++ www/index.html 2007-01-22 10:31:43 UTC (rev 185)
@@ -52,7 +52,7 @@
A channels.conf files can be generated by the "scan" utility in the dvb-apps package at <A HREF="http://www.linuxtv.org">www.linuxtv.org</A>.
If not specified with -f, rb-download will search for:
<UL>
-<LI>~/channels.conf</LI>
+<LI>~/.tzap/channels.conf</LI>
<LI>/etc/channels.conf</LI>
</UL>
<P>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-22 15:23:27
|
Revision: 186
http://svn.sourceforge.net/redbutton/?rev=186&view=rev
Author: skilvington
Date: 2007-01-22 07:23:21 -0800 (Mon, 22 Jan 2007)
Log Message:
-----------
add -d flag to disable all audio and video output
Modified Paths:
--------------
redbutton-browser/trunk/MHEGEngine.c
redbutton-browser/trunk/MHEGEngine.h
redbutton-browser/trunk/MHEGStreamPlayer.c
redbutton-browser/trunk/rb-browser.c
www/index.html
Modified: redbutton-browser/trunk/MHEGEngine.c
===================================================================
--- redbutton-browser/trunk/MHEGEngine.c 2007-01-22 10:31:43 UTC (rev 185)
+++ redbutton-browser/trunk/MHEGEngine.c 2007-01-22 15:23:21 UTC (rev 186)
@@ -174,6 +174,7 @@
MHEGDisplay_init(&engine.display, opts->fullscreen, opts->keymap);
engine.vo_method = MHEGVideoOutputMethod_fromString(opts->vo_method);
+ engine.av_disabled = opts->av_disabled;
MHEGBackend_init(&engine.backend, opts->remote, opts->srg_loc);
@@ -261,7 +262,7 @@
boot_obj.size = engine.quit_data.size;
boot_obj.data = engine.quit_data.data;
break;
-
+
case QuitReason_Spawn:
verbose("Spawn '%.*s'", engine.quit_data.size, engine.quit_data.data);
/* TODO */
@@ -270,12 +271,12 @@
boot_obj.size = engine.quit_data.size;
boot_obj.data = engine.quit_data.data;
break;
-
+
case QuitReason_Retune:
verbose("Retune to '%.*s'", engine.quit_data.size, engine.quit_data.data);
MHEGEngine_retune(&engine.quit_data);
break;
-
+
default:
/* nothing to do */
break;
@@ -316,6 +317,12 @@
return engine.vo_method;
}
+bool
+MHEGEngine_avDisabled(void)
+{
+ return engine.av_disabled;
+}
+
/*
* according to the ISO MHEG spec this should be part of the SceneClass
* but we need info about the current app etc too
Modified: redbutton-browser/trunk/MHEGEngine.h
===================================================================
--- redbutton-browser/trunk/MHEGEngine.h 2007-01-22 10:31:43 UTC (rev 185)
+++ redbutton-browser/trunk/MHEGEngine.h 2007-01-22 15:23:21 UTC (rev 186)
@@ -86,6 +86,7 @@
unsigned int timeout; /* seconds to poll for missing content before generating a ContentRefError */
bool fullscreen; /* scale to fullscreen? */
char *vo_method; /* MHEGVideoOutputMethod name (NULL for default) */
+ bool av_disabled; /* true => audio and video output totally disabled */
char *keymap; /* keymap config file to use (NULL for default) */
} MHEGEngineOptions;
@@ -168,6 +169,7 @@
unsigned int timeout; /* how long to poll for missing content before generating an error */
MHEGDisplay display; /* make porting easier */
MHEGVideoOutputMethod *vo_method; /* video output method (resolved from name given in MHEGEngineOptions) */
+ bool av_disabled; /* true => video and audio output totally disabled */
MHEGBackend backend; /* local or remote access to DSMCC carousel and MPEG streams */
MHEGApp active_app; /* application we are currently running */
QuitReason quit_reason; /* do we need to stop the current app */
@@ -189,6 +191,7 @@
MHEGDisplay *MHEGEngine_getDisplay(void);
MHEGVideoOutputMethod *MHEGEngine_getVideoOutputMethod(void);
+bool MHEGEngine_avDisabled(void);
void MHEGEngine_TransitionTo(TransitionTo *, OctetString *);
Modified: redbutton-browser/trunk/MHEGStreamPlayer.c
===================================================================
--- redbutton-browser/trunk/MHEGStreamPlayer.c 2007-01-22 10:31:43 UTC (rev 185)
+++ redbutton-browser/trunk/MHEGStreamPlayer.c 2007-01-22 15:23:21 UTC (rev 186)
@@ -168,6 +168,10 @@
if(p->video != NULL)
p->video->inst.no_video = true;
+ /* is audio/video output totally disabled */
+ if(MHEGEngine_avDisabled())
+ return;
+
p->audio_pid = p->audio_tag;
p->video_pid = p->video_tag;
if((p->ts = MHEGEngine_openStream(p->have_audio, &p->audio_pid, &p->audio_type,
Modified: redbutton-browser/trunk/rb-browser.c
===================================================================
--- redbutton-browser/trunk/rb-browser.c 2007-01-22 10:31:43 UTC (rev 185)
+++ redbutton-browser/trunk/rb-browser.c 2007-01-22 15:23:21 UTC (rev 186)
@@ -1,8 +1,9 @@
/*
- * rb-browser [-v] [-f] [-o <video_output_method>] [-k <keymap_file>] [-t <timeout>] [-r] <service_gateway>
+ * rb-browser [-v] [-f] [-d] [-o <video_output_method>] [-k <keymap_file>] [-t <timeout>] [-r] <service_gateway>
*
* -v is verbose/debug mode
* -f is full screen, otherwise it uses a window
+ * -d disables all video and audio output
* -o allows you to choose a video output method if the default is not supported/too slow on your graphics card
* (do 'rb-browser -o' for a list of available methods)
* -k changes the default key map to the given file
@@ -49,10 +50,11 @@
opts.verbose = 0;
opts.fullscreen = false;
opts.vo_method = NULL;
+ opts.av_disabled = false;
opts.timeout = MISSING_CONTENT_TIMEOUT;
opts.keymap = NULL;
- while((arg = getopt(argc, argv, "rvfo:k:t:")) != EOF)
+ while((arg = getopt(argc, argv, "rvfdo:k:t:")) != EOF)
{
switch(arg)
{
@@ -68,6 +70,10 @@
opts.fullscreen = true;
break;
+ case 'd':
+ opts.av_disabled = true;
+ break;
+
case 'o':
opts.vo_method = optarg;
break;
@@ -114,6 +120,7 @@
fatal("Usage: %s "
"[-v] "
"[-f] "
+ "[-d] "
"[-o <video_output_method>] "
"[-k <keymap_file>] "
"[-t <timeout>] "
Modified: www/index.html
===================================================================
--- www/index.html 2007-01-22 10:31:43 UTC (rev 185)
+++ www/index.html 2007-01-22 15:23:21 UTC (rev 186)
@@ -95,7 +95,7 @@
<H2>rb-browser</H2>
Usage:
<PRE>
-rb-browser [-v] [-f] [-k <keymap_config_file>] [-t <timeout>] [-r] <service_gateway>
+rb-browser [-v] [-f] [-d] [-o <video_output_method>] [-k <keymap_config_file>] [-t <timeout>] [-r] <service_gateway>
</PRE>
Display the MHEG apps downloaded with rb-download.
<P>
@@ -124,6 +124,11 @@
<P>
It will display the app in a window, use -f for full screen mode.
<P>
+The -d flag disables all audio and video output.
+<P>
+Use -o to choose a video output method if the default is not supported/too slow on your graphics card.
+'rb-browser -o' will give a list of available video output methods.
+<P>
The -v flag enables verbose/debug mode.
<P>
The -t flag determines how long (in seconds) it will poll for missing files before passing an error to the MHEG application.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-29 16:55:41
|
Revision: 203
http://svn.sourceforge.net/redbutton/?rev=203&view=rev
Author: skilvington
Date: 2007-01-29 08:55:28 -0800 (Mon, 29 Jan 2007)
Log Message:
-----------
default backend is "-r 127.0.0.1"
Modified Paths:
--------------
redbutton-browser/trunk/MHEGBackend.h
redbutton-browser/trunk/rb-browser.c
www/index.html
Modified: redbutton-browser/trunk/MHEGBackend.h
===================================================================
--- redbutton-browser/trunk/MHEGBackend.h 2007-01-28 09:52:02 UTC (rev 202)
+++ redbutton-browser/trunk/MHEGBackend.h 2007-01-29 16:55:28 UTC (rev 203)
@@ -12,6 +12,8 @@
/* default TCP port to contact backend on */
#define DEFAULT_REMOTE_PORT 10101
+#define DEFAULT_BACKEND "127.0.0.1"
+
typedef struct MHEGBackend
{
char *base_dir; /* local Service Gateway root directory */
Modified: redbutton-browser/trunk/rb-browser.c
===================================================================
--- redbutton-browser/trunk/rb-browser.c 2007-01-28 09:52:02 UTC (rev 202)
+++ redbutton-browser/trunk/rb-browser.c 2007-01-29 16:55:28 UTC (rev 203)
@@ -1,5 +1,5 @@
/*
- * rb-browser [-v] [-f] [-d] [-o <video_output_method>] [-k <keymap_file>] [-t <timeout>] [-r] <service_gateway>
+ * rb-browser [-v] [-f] [-d] [-o <video_output_method>] [-k <keymap_file>] [-t <timeout>] [-r] [<service_gateway>]
*
* -v is verbose/debug mode
* -f is full screen, otherwise it uses a window
@@ -12,6 +12,8 @@
* -r means use a remote backend (rb-download running on another host), <service_gateway> should be host[:port]
* if -r is not specified, rb-download is running on the same machine
* and <service_gateway> should be an entry in the services directory, eg. services/4165
+ * (this is really only for debugging or running MHEG apps you've written yourself)
+ * the default backend is "-r 127.0.0.1"
*/
#include <unistd.h>
@@ -45,8 +47,8 @@
/* default options */
bzero(&opts, sizeof(MHEGEngineOptions));
- opts.remote = false;
- opts.srg_loc = NULL; /* must be given on cmd line */
+ opts.remote = false; /* not the default, but needed so you do eg "-r services/4165" */
+ opts.srg_loc = DEFAULT_BACKEND;
opts.verbose = 0;
opts.fullscreen = false;
opts.vo_method = NULL;
@@ -92,11 +94,13 @@
}
}
- if(optind != argc - 1)
+ if(optind == argc)
+ opts.remote = true; /* default backend "-r 127.0.0.1" */
+ else if(optind == argc - 1)
+ opts.srg_loc = argv[optind];
+ else
usage(prog_name);
- opts.srg_loc = argv[optind];
-
/* chop off any trailing / chars for local directory name */
if(!opts.remote)
{
@@ -125,7 +129,7 @@
"[-k <keymap_file>] "
"[-t <timeout>] "
"[-r] "
- "<service_gateway>\n\n"
+ "[<service_gateway>]\n\n"
"%s",
prog_name, MHEGVideoOutputMethod_getUsage());
}
Modified: www/index.html
===================================================================
--- www/index.html 2007-01-28 09:52:02 UTC (rev 202)
+++ www/index.html 2007-01-29 16:55:28 UTC (rev 203)
@@ -50,6 +50,10 @@
<P>
rb-download needs a "channels.conf" file which gives tuning parameters for service_id's.
A channels.conf files can be generated by the "scan" utility in the dvb-apps package at <A HREF="http://www.linuxtv.org">www.linuxtv.org</A>.
+For example:
+<PRE>
+scan ./uk-Malvern > ~/.tzap/channels.conf
+</PRE>
If not specified with -f, rb-download will search for:
<UL>
<LI>~/.tzap/channels.conf</LI>
@@ -69,6 +73,10 @@
<P>
If no <service_id> is given, a list of possible channels (and their <service_id>) is printed.
These will be the channels available on the MUX your DVB card is currently tuned to. Use dvbtune or equivalent to tune your card.
+eg:
+<PRE>
+dvbtune -f 722166667 && rb-download
+</PRE>
<P>
The file structure stored under <base_dir> will be:
<PRE>
@@ -95,23 +103,25 @@
<H2>rb-browser</H2>
Usage:
<PRE>
-rb-browser [-v] [-f] [-d] [-o <video_output_method>] [-k <keymap_config_file>] [-t <timeout>] [-r] <service_gateway>
+rb-browser [-v] [-f] [-d] [-o <video_output_method>] [-k <keymap_config_file>] [-t <timeout>] [-r] [<service_gateway>]
</PRE>
Display the MHEG apps downloaded with rb-download.
<P>
The -r option means use a remote backend (rb-download running on another host).
If -r is specified, then <service_gateway> should be the host[:port] that rb-download is running on.
+<P>
+The default backend is "-r 127.0.0.1" ie rb-download running on the same machine as rb-browser.
+<P>
If -r is not specified, rb-download is running on the same machine
and <service_gateway> should be an entry in the services directory.
+This is really only useful for debugging, or running MHEG apps you have written
+yourself.
+<P>
Eg, on a single host, do this:
<PRE>
rb-download 4165 &
-rb-browser services/4165
+rb-browser
</PRE>
-or, you could run rb-browser like this:
-<PRE>
-rb-browser -r 127.0.0.1
-</PRE>
To run the frontend on a different host, do this on the backend:
<PRE>
rb-download 4165 &
@@ -122,6 +132,13 @@
</PRE>
where 10.0.0.1 is the IP or hostname of the backend.
<P>
+To run an MHEG app you have previously downloaded and saved, do this:
+<PRE>
+rb-browser path/to/saved/services/4165
+</PRE>
+Although this will not give you any video or audio as this is streamed from rb-download.
+Retuning will also probably not work unless you've also saved the services directory for the channel you want to retune to.
+<P>
It will display the app in a window, use -f for full screen mode.
<P>
The -d flag disables all audio and video output.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-11 12:38:59
|
Revision: 208
http://svn.sourceforge.net/redbutton/?rev=208&view=rev
Author: skilvington
Date: 2007-02-11 04:38:51 -0800 (Sun, 11 Feb 2007)
Log Message:
-----------
nearly able to stream a/v from different service IDs
Modified Paths:
--------------
redbutton-browser/trunk/MHEGBackend.c
redbutton-download/trunk/command.c
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/findmheg.h
Modified: redbutton-browser/trunk/MHEGBackend.c
===================================================================
--- redbutton-browser/trunk/MHEGBackend.c 2007-02-08 14:07:04 UTC (rev 207)
+++ redbutton-browser/trunk/MHEGBackend.c 2007-02-11 12:38:51 UTC (rev 208)
@@ -540,21 +540,18 @@
unsigned int video_pid = 0;
bool err;
-/* TODO */
-if(service_id != -1) printf("TODO: openStream: service_id=%d\n", service_id);
-
/* no PIDs required */
if(!have_audio && !have_video)
return NULL;
/* video and audio */
else if(have_audio && have_video)
- snprintf(cmd, sizeof(cmd), "avstream %d %d\n", *audio_tag, *video_tag);
+ snprintf(cmd, sizeof(cmd), "avstream %d %d %d\n", service_id, *audio_tag, *video_tag);
/* audio only */
else if(have_audio)
- snprintf(cmd, sizeof(cmd), "astream %d\n", *audio_tag);
+ snprintf(cmd, sizeof(cmd), "astream %d %d\n", service_id, *audio_tag);
/* video only */
else
- snprintf(cmd, sizeof(cmd), "vstream %d\n", *video_tag);
+ snprintf(cmd, sizeof(cmd), "vstream %d %d\n", service_id, *video_tag);
/* false => create a new connection to the backend */
if((sock = remote_command(t, false, cmd)) == NULL)
Modified: redbutton-download/trunk/command.c
===================================================================
--- redbutton-download/trunk/command.c 2007-02-08 14:07:04 UTC (rev 207)
+++ redbutton-download/trunk/command.c 2007-02-11 12:38:51 UTC (rev 208)
@@ -13,6 +13,7 @@
#include <sys/stat.h>
#include "command.h"
+#include "findmheg.h"
#include "assoc.h"
#include "fs.h"
#include "stream.h"
@@ -40,16 +41,16 @@
char *help;
} command[] =
{
- { "assoc", "", cmd_assoc, "List component tag to PID mappings" },
- { "astream", "<ComponentTag>", cmd_astream, "Stream the given audio component tag" },
- { "avstream", "<AudioTag> <VideoTag>", cmd_avstream, "Stream the given audio and video component tags" },
- { "check", "<ContentReference>", cmd_check, "Check if the given file exists on the carousel" },
- { "exit", "", cmd_quit, "Close the connection" },
- { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" },
- { "help", "", cmd_help, "List available commands" },
- { "quit", "", cmd_quit, "Close the connection" },
- { "retune", "<ServiceID>", cmd_retune, "Start downloading the carousel from ServiceID" },
- { "vstream", "<ComponentTag>", cmd_vstream, "Stream the given video component tag" },
+ { "assoc", "", cmd_assoc, "List component tag to PID mappings" },
+ { "astream", "[<ServiceID>] <ComponentTag>", cmd_astream, "Stream the given audio component tag" },
+ { "avstream", "[<ServiceID>] <AudioTag> <VideoTag>", cmd_avstream, "Stream the given audio and video component tags" },
+ { "check", "<ContentReference>", cmd_check, "Check if the given file exists on the carousel" },
+ { "exit", "", cmd_quit, "Close the connection" },
+ { "file", "<ContentReference>", cmd_file, "Retrieve the given file from the carousel" },
+ { "help", "", cmd_help, "List available commands" },
+ { "quit", "", cmd_quit, "Close the connection" },
+ { "retune", "<ServiceID>", cmd_retune, "Start downloading the carousel from ServiceID" },
+ { "vstream", "[<ServiceID>] <ComponentTag>", cmd_vstream, "Stream the given video component tag" },
{ NULL, NULL, NULL, NULL }
};
@@ -133,6 +134,14 @@
return false; \
}
+/* variable number of arguments */
+#define CHECK_VUSAGE(MIN, MAX, SYNTAX) \
+if(argc < MIN || argc > MAX) \
+{ \
+ SEND_RESPONSE(500, "Syntax: " SYNTAX); \
+ return false; \
+}
+
/*
* assoc
* show the association/component tag to PID mappings
@@ -164,48 +173,46 @@
}
/*
- * astream <tag>
+ * astream [<service_id>] <tag>
* send the given audio stream down the connection
+ * if service_id is not specified or is -1, use the service we are downloading the carousel from
* the tag should be an association/component_tag number as found in the PMT
* the tag is converted to a PID and that PID is sent as a MPEG Transport Stream down the connection
- * if tag is -1, the default audio stream for the current service_id is sent
+ * if tag is -1, the default audio stream for the service_id is sent
*/
bool
cmd_astream(struct listen_data *listen_data, FILE *client, int argc, char *argv[])
{
struct carousel *car = listen_data->carousel;
+ int service;
int tag;
- uint16_t pid;
- uint8_t type;
+ struct avstreams *streams;
int audio_fd;
int ts_fd;
char hdr[64];
- CHECK_USAGE(2, "astream <ComponentTag>");
+ CHECK_VUSAGE(2, 3, "astream [<ServiceID>] <ComponentTag>");
- tag = strtol(argv[1], NULL, 0);
-
- /* map the tag to a PID and stream type, or use the default */
- if(tag == -1)
+ if(argc == 2)
{
- /* check we have a default stream */
- if(car->audio_pid == 0)
- {
- SEND_RESPONSE(500, "Unable to find audio PID");
- return false;
- }
- pid = car->audio_pid;
- type = car->audio_type;
+ service = -1;
+ tag = strtol(argv[1], NULL, 0);
}
else
{
- pid = stream2pid(&car->assoc, tag);
- type = stream2type(&car->assoc, tag);
+ service = strtol(argv[1], NULL, 0);
+ tag = strtol(argv[2], NULL, 0);
}
+ streams = find_avstreams(car, service, tag, -1);
+
+ /* check we have a default stream */
+ if(streams->audio_pid == 0)
+ SEND_RESPONSE(500, "Unable to resolve audio PID");
+
/* add the PID to the demux device */
- if((audio_fd = add_demux_filter(car->demux_device, pid, DMX_PES_AUDIO)) < 0)
+ if((audio_fd = add_demux_filter(car->demux_device, streams->audio_pid, DMX_PES_AUDIO)) < 0)
{
SEND_RESPONSE(500, "Unable to open audio PID");
return false;
@@ -223,7 +230,7 @@
SEND_RESPONSE(200, "OK");
/* tell the client what PID and stream type the component tag resolved to */
- snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u\n", pid, type);
+ snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u\n", streams->audio_pid, streams->audio_type);
fputs(hdr, client);
/* shovel the transport stream to client until the client closes or we get an error */
@@ -238,48 +245,46 @@
}
/*
- * vstream <tag>
+ * vstream [<service_id>] <tag>
* send the given video stream down the connection
+ * if service_id is not specified or is -1, use the service we are downloading the carousel from
* the tag should be an association/component_tag number as found in the PMT
* the tag is converted to a PID and that PID is sent as a MPEG Transport Stream down the connection
- * if tag is -1, the default video stream for the current service_id is sent
+ * if tag is -1, the default video stream for the service_id is sent
*/
bool
cmd_vstream(struct listen_data *listen_data, FILE *client, int argc, char *argv[])
{
struct carousel *car = listen_data->carousel;
+ int service;
int tag;
- uint16_t pid;
- uint8_t type;
+ struct avstreams *streams;
int video_fd;
int ts_fd;
char hdr[64];
- CHECK_USAGE(2, "vstream <ComponentTag>");
+ CHECK_VUSAGE(2, 3, "vstream [<ServiceID>] <ComponentTag>");
- tag = strtol(argv[1], NULL, 0);
-
- /* map the tag to a PID and stream type, or use the default */
- if(tag == -1)
+ if(argc == 2)
{
- /* check we have a default stream */
- if(car->video_pid == 0)
- {
- SEND_RESPONSE(500, "Unable to find video PID");
- return false;
- }
- pid = car->video_pid;
- type = car->video_type;
+ service = -1;
+ tag = strtol(argv[1], NULL, 0);
}
else
{
- pid = stream2pid(&car->assoc, tag);
- type = stream2type(&car->assoc, tag);
+ service = strtol(argv[1], NULL, 0);
+ tag = strtol(argv[2], NULL, 0);
}
+ streams = find_avstreams(car, service, -1, tag);
+
+ /* check we have a default stream */
+ if(streams->video_pid == 0)
+ SEND_RESPONSE(500, "Unable to resolve video PID");
+
/* add the PID to the demux device */
- if((video_fd = add_demux_filter(car->demux_device, pid, DMX_PES_VIDEO)) < 0)
+ if((video_fd = add_demux_filter(car->demux_device, streams->video_pid, DMX_PES_VIDEO)) < 0)
{
SEND_RESPONSE(500, "Unable to open video PID");
return false;
@@ -297,7 +302,7 @@
SEND_RESPONSE(200, "OK");
/* tell the client what PID and stream type the component tag resolved to */
- snprintf(hdr, sizeof(hdr), "VideoPID %u VideoType %u\n", pid, type);
+ snprintf(hdr, sizeof(hdr), "VideoPID %u VideoType %u\n", streams->video_pid, streams->video_type);
fputs(hdr, client);
/* shovel the transport stream down client_sock until the client closes it or we get an error */
@@ -314,73 +319,55 @@
/*
* avstream <audio_tag> <video_tag>
* send the given audio and video streams down the connection
+ * if service_id is not specified or is -1, use the service we are downloading the carousel from
* the tags should be association/component_tag numbers as found in the PMT
* the tags are converted to PIDs and those PIDs are sent as a MPEG Transport Stream down the connection
- * if a tag is -1, the default audio or video stream for the current service_id is sent
+ * if a tag is -1, the default audio or video stream for the service_id is sent
*/
bool
cmd_avstream(struct listen_data *listen_data, FILE *client, int argc, char *argv[])
{
struct carousel *car = listen_data->carousel;
+ int service;
int audio_tag;
int video_tag;
- uint16_t audio_pid;
- uint16_t video_pid;
- uint8_t audio_type;
- uint8_t video_type;
+ struct avstreams *streams;
int audio_fd;
int video_fd;
int ts_fd;
char hdr[64];
- CHECK_USAGE(3, "avstream <AudioTag> <VideoTag>");
+ CHECK_VUSAGE(3, 4, "avstream [<ServiceID>] <AudioTag> <VideoTag>");
- audio_tag = strtol(argv[1], NULL, 0);
- video_tag = strtol(argv[2], NULL, 0);
-
- /* map the tags to PIDs and stream types, or use the defaults */
- if(audio_tag == -1)
+ if(argc == 3)
{
- /* check we have a default stream */
- if(car->audio_pid == 0)
- {
- SEND_RESPONSE(500, "Unable to find audio PID");
- return false;
- }
- audio_pid = car->audio_pid;
- audio_type = car->audio_type;
+ service = -1;
+ audio_tag = strtol(argv[1], NULL, 0);
+ video_tag = strtol(argv[2], NULL, 0);
}
else
{
- audio_pid = stream2pid(&car->assoc, audio_tag);
- audio_type = stream2type(&car->assoc, audio_tag);
+ service = strtol(argv[1], NULL, 0);
+ audio_tag = strtol(argv[2], NULL, 0);
+ video_tag = strtol(argv[3], NULL, 0);
}
- if(video_tag == -1)
- {
- /* check we have a default stream */
- if(car->video_pid == 0)
- {
- SEND_RESPONSE(500, "Unable to find video PID");
- return false;
- }
- video_pid = car->video_pid;
- video_type = car->video_type;
- }
- else
- {
- video_pid = stream2pid(&car->assoc, video_tag);
- video_type = stream2type(&car->assoc, video_tag);
- }
+ streams = find_avstreams(car, service, audio_tag, video_tag);
+ /* check we have a default stream */
+ if(streams->audio_pid == 0)
+ SEND_RESPONSE(500, "Unable to resolve audio PID");
+ if(streams->video_pid == 0)
+ SEND_RESPONSE(500, "Unable to resolve video PID");
+
/* add the PIDs to the demux device */
- if((audio_fd = add_demux_filter(car->demux_device, audio_pid, DMX_PES_AUDIO)) < 0)
+ if((audio_fd = add_demux_filter(car->demux_device, streams->audio_pid, DMX_PES_AUDIO)) < 0)
{
SEND_RESPONSE(500, "Unable to open audio PID");
return false;
}
- if((video_fd = add_demux_filter(car->demux_device, video_pid, DMX_PES_VIDEO)) < 0)
+ if((video_fd = add_demux_filter(car->demux_device, streams->video_pid, DMX_PES_VIDEO)) < 0)
{
SEND_RESPONSE(500, "Unable to open video PID");
close(audio_fd);
@@ -400,7 +387,8 @@
SEND_RESPONSE(200, "OK");
/* tell the client what PIDs and stream types the component tags resolved to */
- snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u VideoPID %u VideoType %u\n", audio_pid, audio_type, video_pid, video_type);
+ snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u VideoPID %u VideoType %u\n",
+ streams->audio_pid, streams->audio_type, streams->video_pid, streams->video_type);
fputs(hdr, client);
/* shovel the transport stream down client_sock until the client closes it or we get an error */
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2007-02-08 14:07:04 UTC (rev 207)
+++ redbutton-download/trunk/findmheg.c 2007-02-11 12:38:51 UTC (rev 208)
@@ -26,6 +26,7 @@
#include <netinet/in.h>
#include "carousel.h"
+#include "findmheg.h"
#include "table.h"
#include "assoc.h"
#include "utils.h"
@@ -282,3 +283,38 @@
return &_car;
}
+static struct avstreams _streams;
+
+struct avstreams *
+find_avstreams(struct carousel *car, int service_id, int audio_tag, int video_tag)
+{
+if(service_id != -1) printf("TODO: find_avstreams %d\n", service_id);
+
+ /* map the tags to PIDs and stream types, or use the defaults */
+ if(audio_tag == -1)
+ {
+ /* maybe 0 if we have no default stream */
+ _streams.audio_pid = car->audio_pid;
+ _streams.audio_type = car->audio_type;
+ }
+ else
+ {
+ _streams.audio_pid = stream2pid(&car->assoc, audio_tag);
+ _streams.audio_type = stream2type(&car->assoc, audio_tag);
+ }
+
+ if(video_tag == -1)
+ {
+ /* maybe 0 if we have no default stream */
+ _streams.video_pid = car->video_pid;
+ _streams.video_type = car->video_type;
+ }
+ else
+ {
+ _streams.video_pid = stream2pid(&car->assoc, video_tag);
+ _streams.video_type = stream2type(&car->assoc, video_tag);
+ }
+
+ return &_streams;
+}
+
Modified: redbutton-download/trunk/findmheg.h
===================================================================
--- redbutton-download/trunk/findmheg.h 2007-02-08 14:07:04 UTC (rev 207)
+++ redbutton-download/trunk/findmheg.h 2007-02-11 12:38:51 UTC (rev 208)
@@ -25,7 +25,17 @@
#include <stdint.h>
+struct avstreams
+{
+ uint16_t audio_pid;
+ uint8_t audio_type;
+ uint16_t video_pid;
+ uint8_t video_type;
+};
+
struct carousel *find_mheg(unsigned int, unsigned int, uint16_t, int);
+struct avstreams *find_avstreams(struct carousel *, int, int, int);
+
#endif /* __FINDMHEG_H__ */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-19 17:16:26
|
Revision: 227
http://svn.sourceforge.net/redbutton/?rev=227&view=rev
Author: skilvington
Date: 2007-02-19 09:16:11 -0800 (Mon, 19 Feb 2007)
Log Message:
-----------
cache PAT and PMTs
Modified Paths:
--------------
redbutton-download/trunk/Makefile
redbutton-download/trunk/TODO
redbutton-download/trunk/findmheg.c
redbutton-download/trunk/listen.c
redbutton-download/trunk/rb-download.c
www/index.html
Added Paths:
-----------
redbutton-download/trunk/cache.c
redbutton-download/trunk/cache.h
Modified: redbutton-download/trunk/Makefile
===================================================================
--- redbutton-download/trunk/Makefile 2007-02-19 13:30:26 UTC (rev 226)
+++ redbutton-download/trunk/Makefile 2007-02-19 17:16:11 UTC (rev 227)
@@ -17,6 +17,7 @@
biop.o \
fs.o \
channels.o \
+ cache.o \
utils.o
LIBS=-lz
Modified: redbutton-download/trunk/TODO
===================================================================
--- redbutton-download/trunk/TODO 2007-02-19 13:30:26 UTC (rev 226)
+++ redbutton-download/trunk/TODO 2007-02-19 17:16:11 UTC (rev 227)
@@ -1,5 +1,3 @@
-cache PAT and PMTs
-
need to kill all existing command connections on retune
(listen_data->carousel is stale for them)
Added: redbutton-download/trunk/cache.c
===================================================================
--- redbutton-download/trunk/cache.c (rev 0)
+++ redbutton-download/trunk/cache.c 2007-02-19 17:16:11 UTC (rev 227)
@@ -0,0 +1,125 @@
+/*
+ * cache.c
+ */
+
+/*
+ * Copyright (C) 2007, Simon Kilvington
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "cache.h"
+#include "table.h"
+#include "utils.h"
+
+/*
+ * can't just cache tables in memory because the PMTs are mostly read when we
+ * execute "avstream <service_id> ..." commands
+ * each command is run in a child process, so the memory is lost when the
+ * process ends
+ * so we cache the tables in the file system
+ * all cache items are MAX_TABLE_LEN bytes long
+ */
+
+#define CACHE_DIR "cache"
+
+bool
+cache_init(void)
+{
+ if(mkdir(CACHE_DIR, 0755) < 0 && errno != EEXIST)
+ fatal("Unable to create cache directory '%s': %s", CACHE_DIR, strerror(errno));
+
+ cache_flush();
+
+ return true;
+}
+
+/*
+ * returns false if the item is not in the cache
+ */
+
+bool
+cache_load(char *item, unsigned char *out)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+ size_t nread;
+
+ snprintf(filename, sizeof(filename), "%s/%s", CACHE_DIR, item);
+
+ if((f = fopen(filename, "r")) == NULL)
+ return false;
+
+ nread = fread(out, 1, MAX_TABLE_LEN, f);
+
+ fclose(f);
+
+ return (nread == MAX_TABLE_LEN);
+}
+
+void
+cache_save(char *item, unsigned char *data)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+
+ snprintf(filename, sizeof(filename), "%s/%s", CACHE_DIR, item);
+
+ if((f = fopen(filename, "w")) == NULL)
+ return;
+
+ /* if we don't write it all, we'll find out when we try to load it */
+ fwrite(data, 1, MAX_TABLE_LEN, f);
+
+ fclose(f);
+
+ return;
+}
+
+void
+cache_flush(void)
+{
+ DIR *d;
+ struct dirent *item;
+ char filename[PATH_MAX];
+
+ if((d = opendir(CACHE_DIR)) == NULL)
+ return;
+
+ while((item = readdir(d)) != NULL)
+ {
+ /* skip . and .. */
+ if(strcmp(item->d_name, ".") == 0
+ || strcmp(item->d_name, "..") == 0)
+ continue;
+ snprintf(filename, sizeof(filename), "%s/%s", CACHE_DIR, item->d_name);
+ unlink(filename);
+ }
+
+ closedir(d);
+
+ return;
+}
+
+
Added: redbutton-download/trunk/cache.h
===================================================================
--- redbutton-download/trunk/cache.h (rev 0)
+++ redbutton-download/trunk/cache.h 2007-02-19 17:16:11 UTC (rev 227)
@@ -0,0 +1,36 @@
+/*
+ * cache.h
+ */
+
+/*
+ * Copyright (C) 2007, Simon Kilvington
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CACHE_H__
+#define __CACHE_H__
+
+#include <stdbool.h>
+
+bool cache_init(void);
+
+bool cache_load(char *, unsigned char *);
+void cache_save(char *, unsigned char *);
+
+void cache_flush(void);
+
+#endif /* __CACHE_H__ */
+
Modified: redbutton-download/trunk/findmheg.c
===================================================================
--- redbutton-download/trunk/findmheg.c 2007-02-19 13:30:26 UTC (rev 226)
+++ redbutton-download/trunk/findmheg.c 2007-02-19 17:16:11 UTC (rev 227)
@@ -30,6 +30,7 @@
#include "findmheg.h"
#include "table.h"
#include "assoc.h"
+#include "cache.h"
#include "utils.h"
/* Programme Association Table and Section */
@@ -81,6 +82,7 @@
static struct avstreams *find_current_avstreams(struct carousel *, int, int);
static struct avstreams *find_service_avstreams(struct carousel *, int, int, int);
+static bool read_pat(char *, unsigned int, unsigned char *);
static bool read_pmt(char *, uint16_t, unsigned int, unsigned char *);
bool
@@ -405,9 +407,35 @@
* returns false if it timesout
*/
-bool
+static bool
+read_pat(char *demux, unsigned int timeout, unsigned char *out)
+{
+ /* is it in the cache */
+ if(cache_load("pat", out))
+ return true;
+
+ /* read it from the DVB card */
+ if(!read_table(demux, PID_PAT, TID_PAT, timeout, out))
+ {
+ error("Unable to read PAT");
+ return false;
+ }
+
+ /* cache it */
+ cache_save("pat", out);
+
+ return true;
+}
+
+/*
+ * output buffer must be at least MAX_TABLE_LEN bytes
+ * returns false if it timesout
+ */
+
+static bool
read_pmt(char *demux, uint16_t service_id, unsigned int timeout, unsigned char *out)
{
+ char cache_item[PATH_MAX];
unsigned char pat[MAX_TABLE_LEN];
uint16_t section_length;
uint16_t offset;
@@ -415,12 +443,14 @@
bool found;
bool rc;
+ /* is it in the cache */
+ snprintf(cache_item, sizeof(cache_item), "pmt-%u", service_id);
+ if(cache_load(cache_item, out))
+ return true;
+
/* get the PAT */
- if(!read_table(demux, PID_PAT, TID_PAT, timeout, pat))
- {
- error("Unable to read PAT");
+ if(!read_pat(demux, timeout, pat))
return false;
- }
section_length = 3 + (((pat[1] & 0x0f) << 8) + pat[2]);
@@ -447,7 +477,12 @@
vverbose("PMT PID: %u", map_pid);
/* get the PMT */
- if(!(rc = read_table(demux, map_pid, TID_PMT, timeout, out)))
+ rc = read_table(demux, map_pid, TID_PMT, timeout, out);
+
+ /* cache it */
+ if(rc)
+ cache_save(cache_item, out);
+ else
error("Unable to read PMT");
return rc;
Modified: redbutton-download/trunk/listen.c
===================================================================
--- redbutton-download/trunk/listen.c 2007-02-19 13:30:26 UTC (rev 226)
+++ redbutton-download/trunk/listen.c 2007-02-19 17:16:11 UTC (rev 227)
@@ -20,6 +20,7 @@
#include "findmheg.h"
#include "carousel.h"
#include "channels.h"
+#include "cache.h"
#include "utils.h"
/* listen() backlog, 5 is max for BSD apparently */
@@ -177,6 +178,7 @@
verbose("Retune to service_id %d", retune_id);
/* kill the current downloader process and start a new one */
kill(listen_data.carousel->downloader, SIGKILL);
+ cache_flush();
listen_data.carousel = start_downloader(adapter, timeout, retune_id, -1);
retune_id = -1;
}
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2007-02-19 13:30:26 UTC (rev 226)
+++ redbutton-download/trunk/rb-download.c 2007-02-19 17:16:11 UTC (rev 227)
@@ -71,6 +71,7 @@
#include "carousel.h"
#include "listen.h"
#include "channels.h"
+#include "cache.h"
#include "utils.h"
/* seconds before we assume no DSMCC data is available on this PID */
@@ -146,6 +147,9 @@
}
}
+ if(!cache_init())
+ fatal("Unable to initialise cache");
+
/* initialise channels.conf */
if(!init_channels_conf(channels_file))
error("Unable to open channels.conf file");
Modified: www/index.html
===================================================================
--- www/index.html 2007-02-19 13:30:26 UTC (rev 226)
+++ www/index.html 2007-02-19 17:16:11 UTC (rev 227)
@@ -90,6 +90,10 @@
</PRE>
where <PID> is the PID the carousel was downloaded from
and <CID> is the Carousel ID.
+<PRE>
+./cache/
+</PRE>
+Temporary cache of DVB tables to stop us having to wait for them to be retransmitted everytime we need them.
<P>
Just leave it running and any updated files will be downloaded as they are broadcast.
<H2>Notes</H2>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-04-24 09:57:21
|
Revision: 288
http://svn.sourceforge.net/redbutton/?rev=288&view=rev
Author: skilvington
Date: 2007-04-24 02:57:13 -0700 (Tue, 24 Apr 2007)
Log Message:
-----------
patch from Steven Ellis at OpenMedia NZ to try the FreeSans font if Tiresias is not available
Modified Paths:
--------------
redbutton-browser/trunk/MHEGFont.c
www/index.html
Modified: redbutton-browser/trunk/MHEGFont.c
===================================================================
--- redbutton-browser/trunk/MHEGFont.c 2007-04-15 09:47:31 UTC (rev 287)
+++ redbutton-browser/trunk/MHEGFont.c 2007-04-24 09:57:13 UTC (rev 288)
@@ -107,35 +107,45 @@
* this cost $1000 to licence from Bit Stream
* alternatively, you can download Nebula DigiTV iTuner from http://www.nebula-electronics.com/
* install it on a Windows box and copy C:\Windows\Fonts\tt7268m_802.ttf to your Linux box
- * if you don't have Tiresias Screenfont, we use whatever Xft returns for 'sans' instead
+ * if you don't have Tiresias Screenfont, we try FreeSans instead
+ * if FreeSANS is not available either, we use whatever Xft returns for 'sans'
*/
static char *_default_font_name = NULL;
static char *_font_name_tiresias = "TiresiasScreenfont";
+static char *_font_name_freesans = "FreeSans";
static char *_font_name_sans = "sans";
void
MHEGFont_defaultName(MHEGFont *font)
{
Display *dpy = MHEGEngine_getDisplay()->dpy;
- char *xlfdname = "-*-TiresiasScreenfont-medium-r-normal-*";
- char **names;
+ char *xlfd_tiresias = "-*-TiresiasScreenfont-medium-r-normal-*";
+ char *xlfd_freesans = "-*-freesans-medium-r-normal-*";
+ char **names = NULL;
int count;
/* first time */
if(_default_font_name == NULL)
{
/* do we have Tiresias */
- if((names = XListFonts(dpy, xlfdname, 1, &count)) != NULL)
+ if((names = XListFonts(dpy, xlfd_tiresias, 1, &count)) != NULL)
{
_default_font_name = _font_name_tiresias;
- XFreeFontNames(names);
}
+ else if((names = XListFonts(dpy, xlfd_freesans, 1, &count)) != NULL)
+ {
+ _default_font_name = _font_name_freesans;
+ error("Font '%s' not available; using '%s' for 'rec://font/uk1'", _font_name_tiresias, _font_name_freesans);
+ }
else
{
_default_font_name = _font_name_sans;
error("Font '%s' not available; using '%s' for 'rec://font/uk1'", _font_name_tiresias, _font_name_sans);
}
+ /* clean up */
+ if(names != NULL)
+ XFreeFontNames(names);
}
font->name = _default_font_name;
Modified: www/index.html
===================================================================
--- www/index.html 2007-04-15 09:47:31 UTC (rev 287)
+++ www/index.html 2007-04-24 09:57:13 UTC (rev 288)
@@ -213,8 +213,8 @@
The Australian applications are MHP, not MHEG, so you should probably look at
<A href="http://www.openmhp.org/">www.openmhp.org</A> for something to display them.
<P>
-If the Tiresias Screenfont is not available, rb-browser uses whatever scalable font Xft returns for "sans" instead.
-Note that this font will have different metrics and so may not fit into the spaces in the MHEG apps designed for Tiresias.
+If the Tiresias Screenfont is not available, rb-browser first tries to use the FreeSans font instead. If this is also not available, rb-browser uses whatever scalable font Xft returns for "sans".
+Note that these fonts will have different metrics and so may not fit into the spaces in the MHEG apps designed for Tiresias.
<H2>Contact Details</H2>
I can be contacted here: s.kilvington at eris dot qinetiq com.
</BODY>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-04-27 09:38:35
|
Revision: 296
http://svn.sourceforge.net/redbutton/?rev=296&view=rev
Author: skilvington
Date: 2007-04-27 02:38:23 -0700 (Fri, 27 Apr 2007)
Log Message:
-----------
search for channels.conf is ~/.tzap/, ~/.szap/, etc depending on card type
Modified Paths:
--------------
redbutton-download/trunk/channels.c
redbutton-download/trunk/channels.h
redbutton-download/trunk/rb-download.c
www/index.html
Modified: redbutton-download/trunk/channels.c
===================================================================
--- redbutton-download/trunk/channels.c 2007-04-26 14:37:47 UTC (rev 295)
+++ redbutton-download/trunk/channels.c 2007-04-27 09:38:23 UTC (rev 296)
@@ -42,16 +42,79 @@
static bool get_dvbc_tune_params(uint16_t, struct dvb_frontend_parameters *);
static bool get_atsc_tune_params(uint16_t, struct dvb_frontend_parameters *);
+/*
+ * returns "tzap" if the given DVB adapter is DVB-T,
+ * "szap" if it is DVB-S
+ * "czap" if it is DVB-C
+ * or "azap" if it is ATSC
+ * (may have been better to call one of these to retune rather than doing it ourselves?)
+ */
+
+char *
+zap_name(unsigned int adapter)
+{
+ char fe_dev[PATH_MAX];
+ int fe_fd;
+ struct dvb_frontend_info fe_info;
+ bool got_info;
+
+ /* see what type of DVB device the adapter is */
+ snprintf(fe_dev, sizeof(fe_dev), FE_DEVICE, adapter);
+
+ if((fe_fd = open(fe_dev, O_RDONLY | O_NONBLOCK)) < 0)
+ fatal("open '%s': %s", fe_dev, strerror(errno));
+
+ vverbose("Getting frontend info");
+
+ do
+ {
+ /* maybe interrupted by a signal */
+ got_info = (ioctl(fe_fd, FE_GET_INFO, &fe_info) >= 0);
+ if(!got_info && errno != EINTR)
+ fatal("ioctl FE_GET_INFO: %s", strerror(errno));
+ }
+ while(!got_info);
+
+ close(fe_fd);
+
+ if(fe_info.type == FE_OFDM)
+ {
+ vverbose("Adapter %u is a '%s' DVB-T card", adapter, fe_info.name);
+ return "tzap";
+ }
+ else if(fe_info.type == FE_QPSK)
+ {
+ vverbose("Adapter %u is a '%s' DVB-S card", adapter, fe_info.name);
+ return "szap";
+ }
+ else if(fe_info.type == FE_QAM)
+ {
+ vverbose("Adapter %u is a '%s' DVB-C card", adapter, fe_info.name);
+ return "czap";
+ }
+ else if(fe_info.type == FE_ATSC)
+ {
+ vverbose("Adapter %u is a '%s' ATSC card", adapter, fe_info.name);
+ return "azap";
+ }
+ else
+ {
+ vverbose("Adapter %u (%s); unknown card type %d", adapter, fe_info.name, fe_info.type);
+ return "";
+ }
+}
+
static FILE *_channels = NULL;
/*
* if filename is NULL, it searches for:
- * ~/.tzap/channels.conf
+ * ~/.<zap_name>/channels.conf
* /etc/channels.conf
+ * zap_name should be tzap for DVB-T, szap for DVB-S, czap for DVB-C or azap for ATSC cards
*/
bool
-init_channels_conf(char *filename)
+init_channels_conf(char *zap_name, char *filename)
{
char *home;
char pathname[PATH_MAX];
@@ -63,7 +126,7 @@
{
if((home = getenv("HOME")) != NULL)
{
- snprintf(pathname, sizeof(pathname), "%s/.tzap/channels.conf", home);
+ snprintf(pathname, sizeof(pathname), "%s/.%s/channels.conf", home, zap_name);
verbose("Trying to open %s", pathname);
_channels = fopen(pathname, "r");
}
Modified: redbutton-download/trunk/channels.h
===================================================================
--- redbutton-download/trunk/channels.h 2007-04-26 14:37:47 UTC (rev 295)
+++ redbutton-download/trunk/channels.h 2007-04-27 09:38:23 UTC (rev 296)
@@ -26,8 +26,10 @@
#include <stdint.h>
#include <stdbool.h>
-bool init_channels_conf(char *);
+char *zap_name(unsigned int);
+bool init_channels_conf(char *, char *);
+
bool tune_service_id(unsigned int, unsigned int, uint16_t);
#endif /* __CHANNELS_H__ */
Modified: redbutton-download/trunk/rb-download.c
===================================================================
--- redbutton-download/trunk/rb-download.c 2007-04-26 14:37:47 UTC (rev 295)
+++ redbutton-download/trunk/rb-download.c 2007-04-27 09:38:23 UTC (rev 296)
@@ -20,7 +20,7 @@
* if not specified with -f, rb-download will search for:
* ~/.tzap/channels.conf
* /etc/channels.conf
- *
+ *
* rb-download listens on the network for commands from a remote rb-browser
* the default IP to listen on is 0.0.0.0 (ie all interfaces), the default TCP port is 10101
* the -l option changes the default IP and port
@@ -148,7 +148,7 @@
}
/* initialise channels.conf */
- if(!init_channels_conf(channels_file))
+ if(!init_channels_conf(zap_name(adapter), channels_file))
error("Unable to open channels.conf file");
/* do we need to change the base directory */
Modified: www/index.html
===================================================================
--- www/index.html 2007-04-26 14:37:47 UTC (rev 295)
+++ www/index.html 2007-04-27 09:38:23 UTC (rev 296)
@@ -54,11 +54,12 @@
<PRE>
scan ./uk-Malvern > ~/.tzap/channels.conf
</PRE>
-If not specified with -f, rb-download will search for:
+If not specified with -f, rb-download will search for (in the case of DVB-T cards):
<UL>
<LI>~/.tzap/channels.conf</LI>
<LI>/etc/channels.conf</LI>
</UL>
+For DVB-S cards it will look in ~/.szap/, for DVB-C cards it will look in ~/.czap/ and for ATSC cards it will look in the ~/.azap/ directory.
<P>
rb-download listens on the network for commands from a remote rb-browser.
The default IP to listen on is 0.0.0.0 (ie all interfaces), the default TCP port is 10101.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-05-22 16:13:30
|
Revision: 306
http://svn.sourceforge.net/redbutton/?rev=306&view=rev
Author: skilvington
Date: 2007-05-22 09:13:24 -0700 (Tue, 22 May 2007)
Log Message:
-----------
SI_GetServiceIndex should return -1 if the service is unavailable
Modified Paths:
--------------
redbutton-browser/trunk/MHEGBackend.c
redbutton-browser/trunk/MHEGBackend.h
redbutton-browser/trunk/MHEGEngine.c
redbutton-browser/trunk/MHEGEngine.h
redbutton-browser/trunk/si.c
redbutton-download/trunk/channels.c
redbutton-download/trunk/channels.h
redbutton-download/trunk/command.c
Modified: redbutton-browser/trunk/MHEGBackend.c
===================================================================
--- redbutton-browser/trunk/MHEGBackend.c 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-browser/trunk/MHEGBackend.c 2007-05-22 16:13:24 UTC (rev 306)
@@ -9,6 +9,8 @@
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "MHEGEngine.h"
#include "si.h"
@@ -36,16 +38,18 @@
bool local_loadFile(MHEGBackend *, OctetString *, OctetString *);
FILE *local_openFile(MHEGBackend *, OctetString *);
void local_retune(MHEGBackend *, OctetString *);
+bool local_isServiceAvailable(MHEGBackend *, OctetString *);
static struct MHEGBackendFns local_backend_fns =
{
- local_checkContentRef, /* checkContentRef */
- local_loadFile, /* loadFile */
- local_openFile, /* openFile */
- open_stream, /* openStream */
- close_stream, /* closeStream */
- local_retune, /* retune */
- get_service_url, /* getServiceURL */
+ local_checkContentRef, /* checkContentRef */
+ local_loadFile, /* loadFile */
+ local_openFile, /* openFile */
+ open_stream, /* openStream */
+ close_stream, /* closeStream */
+ local_retune, /* retune */
+ get_service_url, /* getServiceURL */
+ local_isServiceAvailable, /* isServiceAvailable */
};
/* remote backend funcs */
@@ -53,16 +57,18 @@
bool remote_loadFile(MHEGBackend *, OctetString *, OctetString *);
FILE *remote_openFile(MHEGBackend *, OctetString *);
void remote_retune(MHEGBackend *, OctetString *);
+bool remote_isServiceAvailable(MHEGBackend *, OctetString *);
static struct MHEGBackendFns remote_backend_fns =
{
- remote_checkContentRef, /* checkContentRef */
- remote_loadFile, /* loadFile */
- remote_openFile, /* openFile */
- open_stream, /* openStream */
- close_stream, /* closeStream */
- remote_retune, /* retune */
- get_service_url, /* getServiceURL */
+ remote_checkContentRef, /* checkContentRef */
+ remote_loadFile, /* loadFile */
+ remote_openFile, /* openFile */
+ open_stream, /* openStream */
+ close_stream, /* closeStream */
+ remote_retune, /* retune */
+ get_service_url, /* getServiceURL */
+ remote_isServiceAvailable, /* isServiceAvailable */
};
/* public interface */
@@ -621,6 +627,52 @@
}
/*
+ * return true if we are able to receive the given service
+ * service should be in the form "dvb://<network_id>..<service_id>", eg "dvb://233a..4C80"
+ */
+
+bool
+local_isServiceAvailable(MHEGBackend *t, OctetString *service)
+{
+ unsigned int service_id;
+ char service_str[64];
+ char *slash;
+ int prefix_len;
+ char service_dir[PATH_MAX];
+ struct stat stats;
+ bool exists;
+
+ /* assert */
+ if(service->size < 6 || strncmp(service->data, "dvb://", 6) != 0)
+ fatal("local_isServiceAvailable: invalid service '%.*s'", service->size, service->data);
+
+ /* extract the service_id */
+ service_id = si_get_service_id(service);
+ snprintf(service_str, sizeof(service_str), "%u", service_id);
+
+ /*
+ * base_dir is: [path/to/services/]<service_id>
+ * so we just need to replace the last filename component with the new service_id
+ */
+ slash = strrchr(t->base_dir, '/');
+ if(slash == NULL)
+ {
+ /* no preceeding path */
+ snprintf(service_dir, sizeof(service_dir), "%s", service_str);
+ }
+ else
+ {
+ prefix_len = (slash - t->base_dir) + 1;
+ snprintf(service_dir, sizeof(service_dir), "%.*s%s", prefix_len, t->base_dir, service_str);
+ }
+
+ /* see if the directory for the service exists */
+ exists = (stat(service_dir, &stats) == 0);
+
+ return exists;
+}
+
+/*
* remote routines
*/
@@ -781,3 +833,29 @@
return;
}
+/*
+ * return true if we are able to receive the given service
+ * service should be in the form "dvb://<network_id>..<service_id>", eg "dvb://233a..4C80"
+ */
+
+bool
+remote_isServiceAvailable(MHEGBackend *t, OctetString *service)
+{
+ char cmd[128];
+ FILE *sock;
+ bool available = true;
+
+ /* assert */
+ if(service->size < 6 || strncmp(service->data, "dvb://", 6) != 0)
+ fatal("remote_isServiceAvailable: invalid service '%.*s'", service->size, service->data);
+
+ snprintf(cmd, sizeof(cmd), "available %u\n", si_get_service_id(service));
+
+ if((sock = remote_command(t, true, cmd)) == NULL
+ || remote_response(sock) != BACKEND_RESPONSE_OK)
+ {
+ available = false;
+ }
+
+ return available;
+}
Modified: redbutton-browser/trunk/MHEGBackend.h
===================================================================
--- redbutton-browser/trunk/MHEGBackend.h 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-browser/trunk/MHEGBackend.h 2007-05-22 16:13:24 UTC (rev 306)
@@ -44,6 +44,8 @@
void (*retune)(struct MHEGBackend *, OctetString *);
/* return a dvb:// URL for the service we are currently downloading the carousel from */
const OctetString *(*getServiceURL)(struct MHEGBackend *);
+ /* return true if the engine is able to receive the given service (dvb:// URL format) */
+ bool (*isServiceAvailable)(struct MHEGBackend *, OctetString *);
} *fns;
} MHEGBackend;
Modified: redbutton-browser/trunk/MHEGEngine.c
===================================================================
--- redbutton-browser/trunk/MHEGEngine.c 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-browser/trunk/MHEGEngine.c 2007-05-22 16:13:24 UTC (rev 306)
@@ -1476,6 +1476,18 @@
}
/*
+ * return true if the engine is able to receive the given service
+ * service should be in the form "dvb://<network_id>..<service_id>", eg "dvb://233a..4C80"
+ */
+
+bool
+MHEGEngine_isServiceAvailable(OctetString *service)
+{
+ /* ask the backend */
+ return (*(engine.backend.fns->isServiceAvailable))(&engine.backend, service);
+}
+
+/*
* returns the absolute group ID, ie it always starts with "~//"
* returns a ptr to static string that will be overwritten by the next call to this routine
* section 8.3.2 of the UK MHEG Profile says the filename prefixes are:
Modified: redbutton-browser/trunk/MHEGEngine.h
===================================================================
--- redbutton-browser/trunk/MHEGEngine.h 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-browser/trunk/MHEGEngine.h 2007-05-22 16:13:24 UTC (rev 306)
@@ -249,6 +249,8 @@
const OctetString *MHEGEngine_getRecSvcDef(void);
const OctetString *MHEGEngine_getRecSvcCur(void);
+bool MHEGEngine_isServiceAvailable(OctetString *);
+
char *MHEGEngine_absoluteFilename(OctetString *);
/* convert PNG to internal format */
Modified: redbutton-browser/trunk/si.c
===================================================================
--- redbutton-browser/trunk/si.c 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-browser/trunk/si.c 2007-05-22 16:13:24 UTC (rev 306)
@@ -21,6 +21,8 @@
* "rec://svc/lcn/X" - use logical channel number X (eg 1 for BBC1, 3 for ITV1, etc)
*
* we resolve whatever we are given to a dvb:// format URL and store that
+ *
+ * returns -1 if the backend says the given service is not available
*/
int
@@ -54,6 +56,10 @@
if(OctetString_cmp(ref, &si_channel[i]) == 0)
return i;
+ /* does the backend say it is available */
+ if(!MHEGEngine_isServiceAvailable(ref))
+ return -1;
+
/* add it to the list */
si_max_index ++;
si_channel = safe_realloc(si_channel, (si_max_index + 1) * sizeof(OctetString));
Modified: redbutton-download/trunk/channels.c
===================================================================
--- redbutton-download/trunk/channels.c 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-download/trunk/channels.c 2007-05-22 16:13:24 UTC (rev 306)
@@ -610,4 +610,30 @@
return true;
}
+/*
+ * returns true if service_id is listed in the channels file
+ */
+bool
+service_available(uint16_t service_id)
+{
+ char line[1024];
+ char *p;
+ unsigned long id;
+
+ rewind(_channels);
+
+ while(!feof(_channels))
+ {
+ /* service_id is the last field for all channels.conf file formats */
+ if(fgets(line, sizeof(line), _channels) == NULL
+ || (p = rindex(line, ':')) == NULL)
+ continue;
+ id = strtoul(p + 1, NULL, 0);
+ if(id == service_id)
+ return true;
+ }
+
+ return false;
+}
+
Modified: redbutton-download/trunk/channels.h
===================================================================
--- redbutton-download/trunk/channels.h 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-download/trunk/channels.h 2007-05-22 16:13:24 UTC (rev 306)
@@ -32,5 +32,7 @@
bool tune_service_id(unsigned int, unsigned int, uint16_t);
+bool service_available(uint16_t);
+
#endif /* __CHANNELS_H__ */
Modified: redbutton-download/trunk/command.c
===================================================================
--- redbutton-download/trunk/command.c 2007-05-01 12:19:57 UTC (rev 305)
+++ redbutton-download/trunk/command.c 2007-05-22 16:13:24 UTC (rev 306)
@@ -18,6 +18,7 @@
#include "assoc.h"
#include "fs.h"
#include "stream.h"
+#include "channels.h"
#include "utils.h"
/* max number of args that can be passed to a command (arbitrary) */
@@ -27,6 +28,7 @@
bool cmd_assoc(struct listen_data *, FILE *, int, char **);
bool cmd_ademux(struct listen_data *, FILE *, int, char **);
bool cmd_astream(struct listen_data *, FILE *, int, char **);
+bool cmd_available(struct listen_data *, FILE *, int, char **);
bool cmd_avdemux(struct listen_data *, FILE *, int, char **);
bool cmd_avstream(struct listen_data *, FILE *, int, char **);
bool cmd_check(struct listen_data *, FILE *, int, char **);
@@ -49,6 +51,7 @@
{ "assoc", "", cmd_assoc, "List component tag to PID mappings" },
{ "ademux", "[<ServiceID>] <ComponentTag>", cmd_ademux, "Demux the given audio component tag" },
{ "astream", "[<ServiceID>] <ComponentTag>", cmd_astream, "Stream the given audio component tag" },
+ { "available", "<ServiceID>", cmd_available, "Return OK if the ServiceID is available" },
{ "avdemux", "[<ServiceID>] <AudioTag> <VideoTag>", cmd_avdemux, "Demux the given audio and video component tags" },
{ "avstream", "[<ServiceID>] <AudioTag> <VideoTag>", cmd_avstream, "Stream the given audio and video component tags" },
{ "check", "<ContentReference>", cmd_check, "Check if the given file exists on the carousel" },
@@ -670,6 +673,28 @@
}
/*
+ * available <ServiceID>
+ * returns 200 OK if ServiceID is listed in the channels.conf file
+ */
+
+bool
+cmd_available(struct listen_data *listen_data, FILE *client, int argc, char *argv[])
+{
+ unsigned int service_id;
+
+ CHECK_USAGE(2, "available <ServiceID>");
+
+ service_id = strtoul(argv[1], NULL, 0);
+
+ if(service_available(service_id))
+ SEND_RESPONSE(200, "OK");
+ else
+ SEND_RESPONSE(404, "Not Found");
+
+ return false;
+}
+
+/*
* check <ContentReference>
* check if the given file is on the carousel
* ContentReference should be absolute, ie start with "~//"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-09-28 12:44:16
|
Revision: 428
http://redbutton.svn.sourceforge.net/redbutton/?rev=428&view=rev
Author: skilvington
Date: 2007-09-28 05:44:10 -0700 (Fri, 28 Sep 2007)
Log Message:
-----------
berdecode is more useful here
Modified Paths:
--------------
redbutton-author/trunk/Makefile
redbutton-browser/trunk/Makefile
Added Paths:
-----------
redbutton-author/trunk/berdecode.c
Removed Paths:
-------------
redbutton-browser/trunk/berdecode.c
Modified: redbutton-author/trunk/Makefile
===================================================================
--- redbutton-author/trunk/Makefile 2007-09-27 13:23:43 UTC (rev 427)
+++ redbutton-author/trunk/Makefile 2007-09-28 12:44:10 UTC (rev 428)
@@ -35,11 +35,14 @@
.c.o:
${CC} ${CFLAGS} ${DEFS} -c $<
+berdecode: berdecode.c
+ ${CC} ${CFLAGS} ${DEFS} -o berdecode berdecode.c
+
install: mhegc
install -m 755 mhegc ${DESTDIR}/bin
clean:
- rm -f mhegc ccc lex.ccc.c ccc.tab.[ch] lex.parser.c parser.[lch] tokens.h *.o core
+ rm -f mhegc ccc lex.ccc.c ccc.tab.[ch] lex.parser.c parser.[lch] tokens.h *.o berdecode core
tar:
make clean
Copied: redbutton-author/trunk/berdecode.c (from rev 321, redbutton-browser/trunk/berdecode.c)
===================================================================
--- redbutton-author/trunk/berdecode.c (rev 0)
+++ redbutton-author/trunk/berdecode.c 2007-09-28 12:44:10 UTC (rev 428)
@@ -0,0 +1,414 @@
+/*
+ * berdecode [<filename>]
+ *
+ * not a proper decoder, just a quick hack
+ * if no filename is given, read from stdin
+ *
+ * Simon Kilvington, 2/10/2005
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+
+/* how we know when we have got to the end of a BER type */
+#define WANT_EOF -2 /* continue until End-Of-File */
+#define WANT_EOC -1 /* continue until End-Of-Contents octets (00,00) */
+/* 0 or +ve values are the number of bytes until the end of the type */
+
+/* global buffer to read file contents into */
+static char buf[64 * 1024];
+
+int print_next(FILE *, int, int);
+void print_indent(int);
+void print_boolean(FILE *);
+void print_integer(FILE *, unsigned int);
+void print_oid(FILE *, unsigned int);
+
+unsigned int read_file(FILE *, unsigned int, void *);
+
+unsigned int type_number(unsigned int, unsigned int);
+char *universal_typename(unsigned int);
+void hexdump(unsigned char *, size_t);
+
+void usage(char *);
+void fatal(char *, ...);
+
+int
+main(int argc, char *argv[])
+{
+ FILE *in = NULL;
+ int filelen;
+
+ if(argc == 1)
+ {
+ in = stdin;
+ }
+ else if(argc == 2)
+ {
+ if((in = fopen(argv[1], "r")) == NULL)
+ fatal("Unable to open file '%s': %s", argv[1], strerror(errno));
+ }
+ else
+ {
+ usage(argv[0]);
+ }
+
+ filelen = print_next(in, 0, WANT_EOF);
+
+ printf("file length=%d\n", filelen);
+
+ return EXIT_SUCCESS;
+}
+
+int
+print_next(FILE *in, int indent, int wanted)
+{
+ unsigned int type;
+ unsigned int len;
+ unsigned char byte;
+ unsigned int longtype;
+ int nlens;
+ int nbytes = 0;
+
+ do
+ {
+ /* type */
+ nbytes += read_file(in, 1, &byte);
+ type = byte;
+ longtype = 0;
+ if((type & 0x1f) == 0x1f)
+ {
+ /* multi byte type */
+ do
+ {
+ nbytes += read_file(in, 1, &byte);
+ longtype <<= 7;
+ longtype += byte & 0x7f;
+ }
+ while((byte & 0x80) != 0);
+ }
+ if(type != 0)
+ print_indent(indent);
+ switch(type & 0xc0)
+ {
+ case 0x00:
+ //printf("UNIVERSAL");
+ if(type != 0)
+ printf("%s", universal_typename(type));
+ break;
+
+ case 0x40:
+ printf("[APPLICATION %u]", type_number(type, longtype));
+ break;
+
+ case 0x80:
+ printf("[CONTEXT %u]", type_number(type, longtype));
+ break;
+
+ case 0xc0:
+ printf("[PRIVATE %u]", type_number(type, longtype));
+ break;
+ }
+
+ /* length */
+ nbytes += read_file(in, 1, &byte);
+ len = byte;
+ if(len == 0 && type == 0)
+ {
+ /* check we want EOC */
+ if(wanted != WANT_EOC)
+ fatal("Unexpected End-Of-Contents");
+ return nbytes;
+ }
+ else if(len == 0x80)
+ {
+ /* indefinite length */
+ len = WANT_EOC;
+ }
+ else if((len & 0x80) == 0x80)
+ {
+ /* multibyte length field */
+ nlens = len & 0x7f;
+ len = 0;
+ while(nlens > 0)
+ {
+ nbytes += read_file(in, 1, &byte);
+ len <<= 8;
+ len += byte;
+ nlens --;
+ }
+ }
+ if(type == 0 && len != 0)
+ fatal("type=0x%x (%u) len=0x%x (%u)", type, type, len, len);
+
+ /* value */
+ if((type & 0x20) == 0x20)
+ {
+ /* constructed */
+ printf(" {\n");
+ len = print_next(in, indent+1, len);
+ print_indent(indent);
+ printf("}\n");
+ }
+ else if(len == 0)
+ {
+ printf(" value=default\n");
+ }
+ else if(len > 0)
+ {
+ if(len > sizeof(buf))
+ fatal("Value too long (%u)", len);
+ /* BOOLEAN */
+ if(type == 1 && len == 1)
+ print_boolean(in);
+ /* INTEGER */
+ else if(type == 2 && len <= sizeof(int))
+ print_integer(in, len);
+ /* OBJECT IDENTIFIER */
+ else if(type == 6)
+ print_oid(in, len);
+ /* ENUMERATED */
+ else if(type == 10 && len <= sizeof(int))
+ print_integer(in, len);
+ /* default: hexdump the contents */
+ else if(type != 0)
+ {
+ (void) read_file(in, len, buf);
+ printf(" value=(%u bytes):\n", len);
+ hexdump(buf, len);
+ }
+ }
+
+ if(len > 0)
+ nbytes += len;
+
+ if(wanted >= 0 && nbytes > wanted)
+ fatal("Unexpected EOF");
+ }
+ while(nbytes != wanted && !feof(in));
+
+ return nbytes;
+}
+
+void
+print_indent(int indent)
+{
+ indent *= 2;
+
+ for(; indent>0; indent--)
+ printf(" ");
+
+ return;
+}
+
+void
+print_boolean(FILE *in)
+{
+ unsigned char val;
+
+ read_file(in, 1, &val);
+ printf(" value=%s (%u)\n", (val == 0) ? "false" : "true", val);
+
+ return;
+}
+
+void
+print_integer(FILE *in, unsigned int len)
+{
+ int integer;
+ unsigned char byte;
+ unsigned int uval;
+ int negative;
+ int i;
+
+ /* is it -ve */
+ read_file(in, 1, &byte);
+ negative = ((byte & 0x80) == 0x80);
+
+ /* big endian */
+ uval = byte;
+ for(i=1; i<len; i++)
+ {
+ read_file(in, 1, &byte);
+ uval <<= 8;
+ uval += byte;
+ }
+
+ /* sign extend if negative */
+ if(negative)
+ {
+ /* byte order neutral */
+ for(i=len; i<sizeof(int); i++)
+ uval += (0xff << (i * 8));
+ }
+
+ integer = (int) uval;
+
+ printf(" value=%d\n", integer);
+
+ return;
+}
+
+void
+print_oid(FILE *in, unsigned int len)
+{
+ int oid;
+ int oid1, oid2;
+ int i;
+
+ read_file(in, len, buf);
+
+ if((buf[0] & 0x80) == 0x80)
+ fatal("OID with top-bit set");
+ oid1 = buf[0] / 40;
+ oid2 = buf[0] % 40;
+ printf(" value=%u.%u", oid1, oid2);
+
+ i = 1;
+ while(i < len)
+ {
+ if((buf[i] & 0x80) == 0)
+ {
+ oid = buf[i];
+ i ++;
+ }
+ else
+ {
+ oid = 0;
+ while(((buf[i] & 0x80) == 0x80) && i < len)
+ {
+ oid <<= 7;
+ oid += buf[i] & 0x7f;
+ i ++;
+ }
+ oid <<= 7;
+ oid += buf[i];
+ i ++;
+ }
+ printf(".%d", oid);
+ }
+ printf("\n");
+
+ return;
+}
+
+
+unsigned int
+read_file(FILE *in, unsigned int nbytes, void *buf)
+{
+ if(fread(buf, 1, nbytes, in) != nbytes)
+ fatal("EOF");
+
+ return nbytes;
+}
+
+unsigned int
+type_number(unsigned int type, unsigned int longtype)
+{
+ return ((type & 0x1f) == 0x1f) ? longtype : type & 0x1f;
+}
+
+char *
+universal_typename(unsigned int type)
+{
+ type &= 0x1f;
+
+ if(type == 1) return "BOOLEAN";
+ else if(type == 2) return "INTEGER";
+ else if(type == 3) return "BIT-STRING";
+ else if(type == 4) return "OCTET-STRING";
+ else if(type == 5) return "NULL";
+ else if(type == 6) return "OBJECT-IDENTIFIER";
+ else if(type == 7) return "ObjectDescriptor";
+ else if(type == 8) return "EXTERNAL";
+ else if(type == 9) return "REAL";
+ else if(type == 10) return "ENUMERATED";
+ else if(type == 11) return "EMBEDDED-PDV";
+ else if(type == 12) return "UTF8String";
+ else if(type == 16) return "SEQUENCE";
+ else if(type == 17) return "SET";
+ else if(type == 18) return "NumericString";
+ else if(type == 19) return "PrintableString";
+ else if(type == 20) return "T61String";
+ else if(type == 21) return "VideotexString";
+ else if(type == 22) return "IA5String";
+ else if(type == 23) return "UTCTime";
+ else if(type == 24) return "GeneralizedTime";
+ else if(type == 25) return "GraphicString";
+ else if(type == 26) return "VisibleString";
+ else if(type == 27) return "GeneralString";
+ else if(type == 28) return "UniversalString";
+ else if(type == 30) return "BMPString";
+
+ fatal("Unknown UNIVERSAL type %u", type);
+
+ return NULL;
+}
+
+/* number of bytes per line */
+#define HEXDUMP_WIDTH 16
+
+void
+hexdump(unsigned char *data, size_t nbytes)
+{
+ size_t nout;
+ int i;
+
+ nout = 0;
+ while(nout < nbytes)
+ {
+ /* byte offset at start of line */
+ if((nout % HEXDUMP_WIDTH) == 0)
+ printf("0x%.8x ", nout);
+ /* the byte value in hex */
+ printf("%.2x ", data[nout]);
+ /* the ascii equivalent at the end of the line */
+ if((nout % HEXDUMP_WIDTH) == (HEXDUMP_WIDTH - 1))
+ {
+ printf(" ");
+ for(i=HEXDUMP_WIDTH-1; i>=0; i--)
+ printf("%c", isprint(data[nout - i]) ? data[nout - i] : '.');
+ printf("\n");
+ }
+ nout ++;
+ }
+
+ /* the ascii equivalent if we haven't just done it */
+ if((nout % HEXDUMP_WIDTH) != 0)
+ {
+ /* pad to the start of the ascii equivalent */
+ for(i=(nout % HEXDUMP_WIDTH); i<HEXDUMP_WIDTH; i++)
+ printf(" ");
+ printf(" ");
+ /* print the ascii equivalent */
+ nout --;
+ for(i=(nout % HEXDUMP_WIDTH); i>=0; i--)
+ printf("%c", isprint(data[nout - i]) ? data[nout - i] : '.');
+ printf("\n");
+ }
+
+ return;
+}
+
+void
+usage(char *progname)
+{
+ fatal("Usage: %s [<file>]", progname);
+}
+
+void
+fatal(char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ fprintf(stdout, "\n");
+ va_end(args);
+
+ exit(EXIT_FAILURE);
+}
Modified: redbutton-browser/trunk/Makefile
===================================================================
--- redbutton-browser/trunk/Makefile 2007-09-27 13:23:43 UTC (rev 427)
+++ redbutton-browser/trunk/Makefile 2007-09-28 12:44:10 UTC (rev 428)
@@ -123,7 +123,7 @@
install -m 755 rb-keymap ${DESTDIR}/bin
clean:
- rm -f rb-browser rb-keymap xsd2c dertest dertest-mheg.[ch] berdecode *.o ISO13522-MHEG-5.[ch] clone.[ch] rtti.h gmon.out core
+ rm -f rb-browser rb-keymap xsd2c dertest dertest-mheg.[ch] *.o ISO13522-MHEG-5.[ch] clone.[ch] rtti.h gmon.out core
TARDIR=`basename ${PWD}`
Deleted: redbutton-browser/trunk/berdecode.c
===================================================================
--- redbutton-browser/trunk/berdecode.c 2007-09-27 13:23:43 UTC (rev 427)
+++ redbutton-browser/trunk/berdecode.c 2007-09-28 12:44:10 UTC (rev 428)
@@ -1,414 +0,0 @@
-/*
- * berdecode [<filename>]
- *
- * not a proper decoder, just a quick hack
- * if no filename is given, read from stdin
- *
- * Simon Kilvington, 2/10/2005
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-
-/* how we know when we have got to the end of a BER type */
-#define WANT_EOF -2 /* continue until End-Of-File */
-#define WANT_EOC -1 /* continue until End-Of-Contents octets (00,00) */
-/* 0 or +ve values are the number of bytes until the end of the type */
-
-/* global buffer to read file contents into */
-static char buf[64 * 1024];
-
-int print_next(FILE *, int, int);
-void print_indent(int);
-void print_boolean(FILE *);
-void print_integer(FILE *, unsigned int);
-void print_oid(FILE *, unsigned int);
-
-unsigned int read_file(FILE *, unsigned int, void *);
-
-unsigned int type_number(unsigned int, unsigned int);
-char *universal_typename(unsigned int);
-void hexdump(unsigned char *, size_t);
-
-void usage(char *);
-void fatal(char *, ...);
-
-int
-main(int argc, char *argv[])
-{
- FILE *in = NULL;
- int filelen;
-
- if(argc == 1)
- {
- in = stdin;
- }
- else if(argc == 2)
- {
- if((in = fopen(argv[1], "r")) == NULL)
- fatal("Unable to open file '%s': %s", argv[1], strerror(errno));
- }
- else
- {
- usage(argv[0]);
- }
-
- filelen = print_next(in, 0, WANT_EOF);
-
- printf("file length=%d\n", filelen);
-
- return EXIT_SUCCESS;
-}
-
-int
-print_next(FILE *in, int indent, int wanted)
-{
- unsigned int type;
- unsigned int len;
- unsigned char byte;
- unsigned int longtype;
- int nlens;
- int nbytes = 0;
-
- do
- {
- /* type */
- nbytes += read_file(in, 1, &byte);
- type = byte;
- longtype = 0;
- if((type & 0x1f) == 0x1f)
- {
- /* multi byte type */
- do
- {
- nbytes += read_file(in, 1, &byte);
- longtype <<= 7;
- longtype += byte & 0x7f;
- }
- while((byte & 0x80) != 0);
- }
- if(type != 0)
- print_indent(indent);
- switch(type & 0xc0)
- {
- case 0x00:
- //printf("UNIVERSAL");
- if(type != 0)
- printf("%s", universal_typename(type));
- break;
-
- case 0x40:
- printf("[APPLICATION %u]", type_number(type, longtype));
- break;
-
- case 0x80:
- printf("[CONTEXT %u]", type_number(type, longtype));
- break;
-
- case 0xc0:
- printf("[PRIVATE %u]", type_number(type, longtype));
- break;
- }
-
- /* length */
- nbytes += read_file(in, 1, &byte);
- len = byte;
- if(len == 0 && type == 0)
- {
- /* check we want EOC */
- if(wanted != WANT_EOC)
- fatal("Unexpected End-Of-Contents");
- return nbytes;
- }
- else if(len == 0x80)
- {
- /* indefinite length */
- len = WANT_EOC;
- }
- else if((len & 0x80) == 0x80)
- {
- /* multibyte length field */
- nlens = len & 0x7f;
- len = 0;
- while(nlens > 0)
- {
- nbytes += read_file(in, 1, &byte);
- len <<= 8;
- len += byte;
- nlens --;
- }
- }
- if(type == 0 && len != 0)
- fatal("type=0x%x (%u) len=0x%x (%u)", type, type, len, len);
-
- /* value */
- if((type & 0x20) == 0x20)
- {
- /* constructed */
- printf(" {\n");
- len = print_next(in, indent+1, len);
- print_indent(indent);
- printf("}\n");
- }
- else if(len == 0)
- {
- printf(" value=default\n");
- }
- else if(len > 0)
- {
- if(len > sizeof(buf))
- fatal("Value too long (%u)", len);
- /* BOOLEAN */
- if(type == 1 && len == 1)
- print_boolean(in);
- /* INTEGER */
- else if(type == 2 && len <= sizeof(int))
- print_integer(in, len);
- /* OBJECT IDENTIFIER */
- else if(type == 6)
- print_oid(in, len);
- /* ENUMERATED */
- else if(type == 10 && len <= sizeof(int))
- print_integer(in, len);
- /* default: hexdump the contents */
- else if(type != 0)
- {
- (void) read_file(in, len, buf);
- printf(" value=(%u bytes):\n", len);
- hexdump(buf, len);
- }
- }
-
- if(len > 0)
- nbytes += len;
-
- if(wanted >= 0 && nbytes > wanted)
- fatal("Unexpected EOF");
- }
- while(nbytes != wanted && !feof(in));
-
- return nbytes;
-}
-
-void
-print_indent(int indent)
-{
- indent *= 2;
-
- for(; indent>0; indent--)
- printf(" ");
-
- return;
-}
-
-void
-print_boolean(FILE *in)
-{
- unsigned char val;
-
- read_file(in, 1, &val);
- printf(" value=%s (%u)\n", (val == 0) ? "false" : "true", val);
-
- return;
-}
-
-void
-print_integer(FILE *in, unsigned int len)
-{
- int integer;
- unsigned char byte;
- unsigned int uval;
- int negative;
- int i;
-
- /* is it -ve */
- read_file(in, 1, &byte);
- negative = ((byte & 0x80) == 0x80);
-
- /* big endian */
- uval = byte;
- for(i=1; i<len; i++)
- {
- read_file(in, 1, &byte);
- uval <<= 8;
- uval += byte;
- }
-
- /* sign extend if negative */
- if(negative)
- {
- /* byte order neutral */
- for(i=len; i<sizeof(int); i++)
- uval += (0xff << (i * 8));
- }
-
- integer = (int) uval;
-
- printf(" value=%d\n", integer);
-
- return;
-}
-
-void
-print_oid(FILE *in, unsigned int len)
-{
- int oid;
- int oid1, oid2;
- int i;
-
- read_file(in, len, buf);
-
- if((buf[0] & 0x80) == 0x80)
- fatal("OID with top-bit set");
- oid1 = buf[0] / 40;
- oid2 = buf[0] % 40;
- printf(" value=%u.%u", oid1, oid2);
-
- i = 1;
- while(i < len)
- {
- if((buf[i] & 0x80) == 0)
- {
- oid = buf[i];
- i ++;
- }
- else
- {
- oid = 0;
- while(((buf[i] & 0x80) == 0x80) && i < len)
- {
- oid <<= 7;
- oid += buf[i] & 0x7f;
- i ++;
- }
- oid <<= 7;
- oid += buf[i];
- i ++;
- }
- printf(".%d", oid);
- }
- printf("\n");
-
- return;
-}
-
-
-unsigned int
-read_file(FILE *in, unsigned int nbytes, void *buf)
-{
- if(fread(buf, 1, nbytes, in) != nbytes)
- fatal("EOF");
-
- return nbytes;
-}
-
-unsigned int
-type_number(unsigned int type, unsigned int longtype)
-{
- return ((type & 0x1f) == 0x1f) ? longtype : type & 0x1f;
-}
-
-char *
-universal_typename(unsigned int type)
-{
- type &= 0x1f;
-
- if(type == 1) return "BOOLEAN";
- else if(type == 2) return "INTEGER";
- else if(type == 3) return "BIT-STRING";
- else if(type == 4) return "OCTET-STRING";
- else if(type == 5) return "NULL";
- else if(type == 6) return "OBJECT-IDENTIFIER";
- else if(type == 7) return "ObjectDescriptor";
- else if(type == 8) return "EXTERNAL";
- else if(type == 9) return "REAL";
- else if(type == 10) return "ENUMERATED";
- else if(type == 11) return "EMBEDDED-PDV";
- else if(type == 12) return "UTF8String";
- else if(type == 16) return "SEQUENCE";
- else if(type == 17) return "SET";
- else if(type == 18) return "NumericString";
- else if(type == 19) return "PrintableString";
- else if(type == 20) return "T61String";
- else if(type == 21) return "VideotexString";
- else if(type == 22) return "IA5String";
- else if(type == 23) return "UTCTime";
- else if(type == 24) return "GeneralizedTime";
- else if(type == 25) return "GraphicString";
- else if(type == 26) return "VisibleString";
- else if(type == 27) return "GeneralString";
- else if(type == 28) return "UniversalString";
- else if(type == 30) return "BMPString";
-
- fatal("Unknown UNIVERSAL type %u", type);
-
- return NULL;
-}
-
-/* number of bytes per line */
-#define HEXDUMP_WIDTH 16
-
-void
-hexdump(unsigned char *data, size_t nbytes)
-{
- size_t nout;
- int i;
-
- nout = 0;
- while(nout < nbytes)
- {
- /* byte offset at start of line */
- if((nout % HEXDUMP_WIDTH) == 0)
- printf("0x%.8x ", nout);
- /* the byte value in hex */
- printf("%.2x ", data[nout]);
- /* the ascii equivalent at the end of the line */
- if((nout % HEXDUMP_WIDTH) == (HEXDUMP_WIDTH - 1))
- {
- printf(" ");
- for(i=HEXDUMP_WIDTH-1; i>=0; i--)
- printf("%c", isprint(data[nout - i]) ? data[nout - i] : '.');
- printf("\n");
- }
- nout ++;
- }
-
- /* the ascii equivalent if we haven't just done it */
- if((nout % HEXDUMP_WIDTH) != 0)
- {
- /* pad to the start of the ascii equivalent */
- for(i=(nout % HEXDUMP_WIDTH); i<HEXDUMP_WIDTH; i++)
- printf(" ");
- printf(" ");
- /* print the ascii equivalent */
- nout --;
- for(i=(nout % HEXDUMP_WIDTH); i>=0; i--)
- printf("%c", isprint(data[nout - i]) ? data[nout - i] : '.');
- printf("\n");
- }
-
- return;
-}
-
-void
-usage(char *progname)
-{
- fatal("Usage: %s [<file>]", progname);
-}
-
-void
-fatal(char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- vfprintf(stdout, fmt, args);
- fprintf(stdout, "\n");
- va_end(args);
-
- exit(EXIT_FAILURE);
-}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|