<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    This patch adds the feature where dvblast will write to an external
    file data that can be used by mrtg to display graphs of input bytes
    and any errors. The errors are split into sequence errors and TS
    packets with the error bit set, and finally any packets with the
    scrambling bit set.<br>
    <br>
    We have used -Z for the command line arg, but I see that has been
    used by a recent change.<br>
    <br>
    <br>
    <br>
    diff -Naur dvblast-svn-31-3-2011.orig/dvblast.c
    dvblast-svn-31-3-2011/dvblast.c<br>
    --- dvblast-svn-31-3-2011.orig/dvblast.c    2011-03-31
    13:12:32.000000000 +0100<br>
    +++ dvblast-svn-31-3-2011/dvblast.c    2011-05-31 16:37:48.000000000
    +0100<br>
    @@ -48,6 +48,8 @@<br>
     #include <bitstream/dvb/si.h><br>
     #include <bitstream/ietf/rtp.h><br>
     <br>
    +#include "mrtg-cnt.h"<br>
    +<br>
 /*****************************************************************************<br>
      * Local declarations<br>
     
*****************************************************************************/<br>
    @@ -102,6 +104,9 @@<br>
     static mtime_t i_retention_global = DEFAULT_MAX_RETENTION;<br>
     static int i_ttl_global = 64;<br>
     <br>
    +/* TPS Input log filename */<br>
    +char * psz_mrtg_file = NULL;<br>
    +<br>
     void (*pf_Open)( void ) = NULL;<br>
     block_t * (*pf_Read)( mtime_t i_poll_timeout ) = NULL;<br>
     void (*pf_Reset)( void ) = NULL;<br>
    @@ -438,6 +443,7 @@<br>
         msg_Raw( NULL, "  -Q --quit-timeout     when locked, quit after
    this delay (in ms), or after the first lock timeout" );<br>
         msg_Raw( NULL, "  -r --remote-socket <remote socket>" );<br>
         msg_Raw( NULL, "  -V --version          only display the
    version" );<br>
    +    msg_Raw( NULL, "  -Z mrtg-file <file>   Log input packets
    and errors into mrtg-file" );<br>
         exit(1);<br>
     }<br>
     <br>
    @@ -508,7 +514,7 @@<br>
             { 0, 0, 0, 0 }<br>
         };<br>
     <br>
    -    while ( (c = getopt_long(i_argc, pp_argv,
    "q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:D:A:lCeM:N:j:J:x:Q:hV",
    long_options, NULL)) != -1 )<br>
    +    while ( (c = getopt_long(i_argc, pp_argv,
    "q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:D:A:lCeM:N:j:J:x:Q:hViZ:",
    long_options, NULL)) != -1 )<br>
         {<br>
             switch ( c )<br>
             {<br>
    @@ -751,6 +757,10 @@<br>
                 exit(0);<br>
                 break;<br>
     <br>
    +        case 'Z':<br>
    +            psz_mrtg_file = optarg;<br>
    +            break;<br>
    +<br>
             case 'h':<br>
             default:<br>
                 usage();<br>
    @@ -855,6 +865,9 @@<br>
         srand( time(NULL) * getpid() );<br>
     <br>
         demux_Open();<br>
    + <br>
    +    // init the mrtg logfile<br>
    +    mrtgInit(psz_mrtg_file);<br>
     <br>
         if ( i_priority > 0 )<br>
         {<br>
    @@ -888,13 +901,16 @@<br>
                 exit(EXIT_SUCCESS);<br>
     <br>
             p_ts = pf_Read( i_poll_timeout );<br>
    -        if ( p_ts != NULL )<br>
    +        if ( p_ts != NULL ) {<br>
    +        mrtgAnalyse(p_ts);<br>
                 demux_Run( p_ts );<br>
    +        }<br>
             i_poll_timeout = output_Send();<br>
             if ( i_poll_timeout == -1 || i_poll_timeout >
    MAX_POLL_TIMEOUT )<br>
                 i_poll_timeout = MAX_POLL_TIMEOUT;<br>
         }<br>
     <br>
    +    mrtgClose();<br>
         if ( b_enable_syslog )<br>
             msg_Disconnect();<br>
         return EXIT_SUCCESS;<br>
    diff -Naur dvblast-svn-31-3-2011.orig/Makefile
    dvblast-svn-31-3-2011/Makefile<br>
    --- dvblast-svn-31-3-2011.orig/Makefile    2011-03-31
    13:12:32.000000000 +0100<br>
    +++ dvblast-svn-31-3-2011/Makefile    2011-05-31 16:37:48.000000000
    +0100<br>
    @@ -10,7 +10,7 @@<br>
     LDLIBS += -lrt<br>
     LDLIBS_DVBLAST += -lpthread<br>
     <br>
    -OBJ_DVBLAST = dvblast.o util.o dvb.o udp.o asi.o demux.o output.o
    en50221.o comm.o<br>
    +OBJ_DVBLAST = dvblast.o util.o dvb.o udp.o asi.o demux.o output.o
    en50221.o comm.o mrtg-cnt.o<br>
     OBJ_DVBLASTCTL = util.o dvblastctl.o<br>
     <br>
     PREFIX ?= /usr/local<br>
    diff -Naur dvblast-svn-31-3-2011.orig/mrtg-cnt.c
    dvblast-svn-31-3-2011/mrtg-cnt.c<br>
    --- dvblast-svn-31-3-2011.orig/mrtg-cnt.c    1970-01-01
    01:00:00.000000000 +0100<br>
    +++ dvblast-svn-31-3-2011/mrtg-cnt.c    2011-05-31
    16:37:48.000000000 +0100<br>
    @@ -0,0 +1,176 @@<br>
    +// vim: set shiftwidth=4 tabstop=4 expandtab autoindent :<br>
    +//////////////////////////////////////////////////////////////////<br>
    +// Handle dvb TS packets and count them for MRTG<br>
    +///////////////////////////////////////////////////<br>
    +// Copyright Tripleplay service 2004,2005<br>
    +///////////////////////////////////////////////////<br>
    +<br>
    +#include <stdint.h><br>
    +#include <stdlib.h><br>
    +#include <string.h><br>
    +#include <stdio.h><br>
    +#include <stdbool.h><br>
    +#include <sys/types.h><br>
    +<br>
    +#include <unistd.h><br>
    +#include <fcntl.h><br>
    +#include <sys/time.h><br>
    +<br>
    +#include "dvblast.h"<br>
    +<br>
    +// File handle<br>
    +static FILE *mrtg_fh = NULL;<br>
    +<br>
    +// Counts<br>
    +static long long l_mrtg_packets = 0;    // Packets received<br>
    +static long long l_mrtg_seq_err_packets = 0;    // Out of sequence
    packets received<br>
    +static long long l_mrtg_error_packets = 0;      // Packets received
    with the error flag set<br>
    +static long long l_mrtg_scram_packets = 0;      // Scrambled
    Packets received<br>
    +<br>
    +// Reporting timer<br>
    +#if defined( WIN32 )<br>
    +static LARGE_INTEGER mrtg_time;<br>
    +static LARGE_INTEGER mrtg_inc;<br>
    +#else<br>
    +static struct timeval mrtg_time = { 0, 0 };<br>
    +#endif<br>
    +<br>
    +// Define the dump period in seconds<br>
    +#define MRTG_INTERVAL   10<br>
    +<br>
    +// Pid sequence numbers<br>
    +#define PIDS    0x2000<br>
    +static signed char i_pid_seq[PIDS];<br>
    +<br>
    +// Report the mrtg counters: bytes received, error packets &
    sequence errors<br>
    +static void dumpCounts()<br>
    +{<br>
    +    unsigned int multiplier = 1;        //MRTG_INTERVAL;<br>
    +    if(mrtg_fh) {<br>
    +        rewind(mrtg_fh);<br>
    +        fprintf(mrtg_fh, "%lld %lld %lld %lld\n",<br>
    +                l_mrtg_packets * 188 * multiplier,<br>
    +                l_mrtg_error_packets * multiplier,<br>
    +                l_mrtg_seq_err_packets * multiplier,<br>
    +                l_mrtg_scram_packets * multiplier);<br>
    +        fflush(mrtg_fh);<br>
    +    }<br>
    +}<br>
    +<br>
    +// analyse the input block counting packets and errors<br>
    +// The input is a pointer to a block_t structure, which might be a
    linked list<br>
    +// of blocks. Each block has one TS packet.<br>
    +int mrtgAnalyse(block_t * p_ts)<br>
    +{<br>
    +    unsigned int i_pid;<br>
    +    block_t *p_block = p_ts;<br>
    +    <br>
    +    while (p_block != NULL) {<br>
    +        uint8_t *ts_packet = p_block->p_ts;<br>
    +<br>
    +        char i_seq, i_last_seq;<br>
    +        l_mrtg_packets++;<br>
    +<br>
    +        if (ts_packet[0] != 0x47) {<br>
    +            l_mrtg_error_packets++;<br>
    +            p_block = p_block->p_next;<br>
    +            continue;<br>
    +        }<br>
    +<br>
    +        if (ts_packet[1] & 0x80) {<br>
    +            l_mrtg_error_packets++;<br>
    +            p_block = p_block->p_next;<br>
    +            continue;<br>
    +        }<br>
    +<br>
    +        i_pid = (ts_packet[1] & 0x1f) << 8 |
    ts_packet[2];<br>
    +<br>
    +        // Just count null packets - don't check the sequence
    numbering<br>
    +        if (i_pid == 0x1fff) {<br>
    +            p_block = p_block->p_next;<br>
    +            continue;<br>
    +        }<br>
    +<br>
    +        if (ts_packet[3] & 0xc0) {<br>
    +            l_mrtg_scram_packets++;<br>
    +        }<br>
    +        // Check the sequence numbering<br>
    +        i_seq = ts_packet[3] & 0xf;<br>
    +        i_last_seq = i_pid_seq[i_pid];<br>
    +<br>
    +        if (i_last_seq == -1) {<br>
    +            // First packet - ignore the sequence<br>
    +        } else if (ts_packet[3] & 0x10) {<br>
    +            // Packet contains payload - sequence should be up by
    one<br>
    +            if (i_seq != ((i_last_seq + 1) & 0x0f)) {<br>
    +                l_mrtg_seq_err_packets++;<br>
    +            }<br>
    +        } else {<br>
    +            // Packet contains no payload - sequence should be
    unchanged<br>
    +            if (i_seq != i_last_seq) {<br>
    +                l_mrtg_seq_err_packets++;<br>
    +            }<br>
    +        }<br>
    +        i_pid_seq[i_pid] = i_seq;<br>
    +<br>
    +        // Look at next block<br>
    +        p_block = p_block->p_next;<br>
    +    }<br>
    +<br>
    +    // All blocks processed. See if we need to dump the stats<br>
    +    struct timeval now;<br>
    +    gettimeofday(&now, NULL);<br>
    +    if (timercmp(&now, &mrtg_time, >)) {<br>
    +        // Time to report the mrtg counters<br>
    +        dumpCounts();<br>
    +<br>
    +        // Set the timer for next time<br>
    +        //<br>
    +        // Normally we add the interval to the previous time so
    that if one<br>
    +        // dump is a bit late, the next one still occurs at the
    correct time.<br>
    +        // However, if there is a long gap (e.g. because the
    channel has<br>
    +        // stopped for some time), then just rebase the timing to
    the current<br>
    +        // time.  I've chosen MRTG_INTERVAL as the long gap - this
    is arbitary<br>
    +        if ((now.tv_sec - mrtg_time.tv_sec) > MRTG_INTERVAL) {<br>
    +            msg_Dbg(NULL, "Dump is %d seconds late - reset
    timing\n",<br>
    +                    (int) (now.tv_sec - mrtg_time.tv_sec));<br>
    +            mrtg_time = now;<br>
    +        }<br>
    +        mrtg_time.tv_sec += MRTG_INTERVAL;<br>
    +    }<br>
    +<br>
    +    return 0;<br>
    +}<br>
    +<br>
    +int mrtgInit(char *mrtg_file)<br>
    +{<br>
    +<br>
    +    /* Open MRTG file */<br>
    +    msg_Dbg(NULL, "Opening mrtg file %s.\n", mrtg_file);<br>
    +    if ((mrtg_fh = fopen(mrtg_file, "wb")) == NULL) {<br>
    +        msg_Err(NULL, "unable to open mrtg file");<br>
    +        return -1;<br>
    +    }<br>
    +    // Initialise the file<br>
    +    fprintf(mrtg_fh, "0 0 0 0\n");<br>
    +    fflush(mrtg_fh);<br>
    +<br>
    +    // Initialise the sequence numbering<br>
    +    memset(&i_pid_seq[0], -1, sizeof(signed char) * PIDS);<br>
    +<br>
    +    // Set the reporting timer<br>
    +    gettimeofday(&mrtg_time, NULL);<br>
    +    mrtg_time.tv_sec += MRTG_INTERVAL;<br>
    +<br>
    +    return 0;<br>
    +}<br>
    +<br>
    +void mrtgClose()<br>
    +{<br>
    +    // This is only for testing when using filetest.<br>
    +    if (mrtg_fh) {<br>
    +        dumpCounts();<br>
    +        fclose(mrtg_fh);<br>
    +        mrtg_fh = NULL;<br>
    +    }<br>
    +}<br>
    diff -Naur dvblast-svn-31-3-2011.orig/mrtg-cnt.h
    dvblast-svn-31-3-2011/mrtg-cnt.h<br>
    --- dvblast-svn-31-3-2011.orig/mrtg-cnt.h    1970-01-01
    01:00:00.000000000 +0100<br>
    +++ dvblast-svn-31-3-2011/mrtg-cnt.h    2011-05-31
    16:37:48.000000000 +0100<br>
    @@ -0,0 +1,13 @@<br>
    +// vim: set shiftwidth=4 tabstop=4 expandtab autoindent :<br>
    +///////////////////////////////////////////////////<br>
    +// Copyright Tripleplay service 2004,2005<br>
    +///////////////////////////////////////////////////<br>
    +<br>
    +#ifndef MRTG_CNT_H<br>
    +#define MRTG_CNT_H<br>
    +<br>
    +int mrtgInit(char *mrtg_file);<br>
    +void mrtgClose();<br>
    +int mrtgAnalyse(block_t * p_ts);<br>
    +<br>
    +#endif<br>
    <br>
    <div class="moz-signature">-- <br>
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <title>Tripleplay Signature - Poole</title>
      <font style=""> <br>
        <font size="2">Best Regards,</font><br>
        <br>
        <b>Dr. Peter Martin</b><br>
        <font size="2" color="#404041">Chief Technical Officer</font><br>
        <br>
        Tripleplay Services Ltd<br>
        <br>
        Tel: +44 (0) 845 643 2057</font><br>
      Support: +44 (0) 845 094 3357<br>
      Mobile: +44 (0) 7810 876713<br>
      Mail: <a href="mailto:peter.martin@tripleplay-services.com">peter.martin@tripleplay-services.com</a><br>
      WWW: <a href="http://www.tripleplay-services.com">http://www.tripleplay-services.com</a><br>
      <br>
      <b><font size="2" color="#404041">Tripleplay Services Ltd.</font></b><br>
      <font size="2" color="#404041">Unit 3, Concept Park, Yarrow Road,
        POOLE, DORSET, BH12 4QT</font><br>
      <br>
      <i><font size="2" color="#404041">This message is for the
          designated recipient only and may contain privileged,
          proprietary, or otherwise private information. If you have
          received it in error, please notify the sender immediately and
          delete the original. Any review, retransmission, dissemination
          or other use of, or taking of any action in reliance upon,
          this information by persons or entities other than the
          intended recipient is prohibited </font></i><br>
      <br>
      <i><font size="2" color="#404041">Tripleplay Services Limited is a
          private limited liability company in England and Wales, whose
          registered office is Cromwell House, 14 Fulwood Place, London,
          WC1V 6HZ. Registered in England, number 4338092.</font></i></div>
  </body>
</html>