[dvblast-devel] Impove EPG support + assorted fixes

Georgi Chorbadzhiyski gf at unixsol.org
Sun Jan 14 20:50:44 CET 2018


Second version of EPG improvement patch(es) + some assorted fixes
that I've made while in the area.

All patches are available in https://github.com/gfto/dvblast.git branch 'fixes'

Georgi Chorbadzhiyski (9):
      Add apsk_16 and apsk_32 modulation in documentation
      Show TURBO_FEC flag if it's supported by the frontend
      demux: Do not log EIT tables by default
      demux: Track each EIT PSI table separately
      dvblastctl: Add support for getting EIT present/following/schedule for chosen service
      Remove invalid UTF-8 characters from text output
      dvblastctl: Add --system-charset/-j option
      dvblastctl: Add --timeout/-t option and set default to 15 seconds.
      Add --lnb-type option to dvblast

-- 
Georgi Chorbadzhiyski | http://georgi.unixsol.org/ | http://github.com/gfto/
-------------- next part --------------
From 77bd9fbea66b2936afe87fc74345c95ab14829ee Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sat, 13 Jan 2018 10:05:47 +0200
Subject: [PATCH 1/9] Add apsk_16 and apsk_32 modulation in documentation

---
 README    | 8 +++++---
 dvblast.1 | 2 +-
 dvblast.c | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/README b/README
index 48a2432..261d0c4 100644
--- a/README
+++ b/README
@@ -40,9 +40,11 @@ for instance for DVB-S :
 
 dvblast -f 11570000 -s 27500000 -v 18
 
-This tunes to frequency 11570 MHz, symbol rate 27500, horizontal (-v 18). For
-DVB-S2, you must indicate a modulation with -m qpsk or -m psk_8. For DVB-T,
-a bandwidth (usually -b 8 for 8 MHz multiplexes).
+This tunes to frequency 11570 MHz, symbol rate 27500, horizontal (-v 18).
+
+For DVB-S2 you must indicate a modulation with -m qpsk|psk_8|apsk_16|apsk_32.
+
+For DVB-T you must indicate a bandwidth, usually -b 8 for 8 MHz multiplexes.
 
 Please note that frequencies are in kHz for DVB-S/S2/C, but Hz for DVB-T.
 Symbol rates are in symbols/s, and bandwidths in MHz. If you have several
diff --git a/dvblast.1 b/dvblast.1
index 5f241f3..f9d8212 100644
--- a/dvblast.1
+++ b/dvblast.1
@@ -129,7 +129,7 @@ DVB-C  qpsk|qam_16|qam_32|qam_64|qam_128|qam_256 (default qam_auto)
 .br
 DVB-T  qam_16|qam_32|qam_64|qam_128|qam_256 (default qam_auto)
 .br
-DVB-S2 qpsk|psk_8 (default legacy DVB-S)
+DVB-S2 qpsk|psk_8|apsk_16|apsk_32 (default legacy DVB-S)
 .TP
 \fB\-M\fR, \fB\-\-network-name\fR <name>
 DVB network name to declare in the NIT
diff --git a/dvblast.c b/dvblast.c
index 01f29f0..e0403f7 100644
--- a/dvblast.c
+++ b/dvblast.c
@@ -651,7 +651,7 @@ void usage()
     msg_Raw( NULL, "  -m --modulation       Modulation type" );
     msg_Raw( NULL, "    DVB-C  qpsk|qam_16|qam_32|qam_64|qam_128|qam_256 (default qam_auto)" );
     msg_Raw( NULL, "    DVB-T  qam_16|qam_32|qam_64|qam_128|qam_256 (default qam_auto)" );
-    msg_Raw( NULL, "    DVB-S2 qpsk|psk_8 (default legacy DVB-S)" );
+    msg_Raw( NULL, "    DVB-S2 qpsk|psk_8|apsk_16|apsk_32 (default legacy DVB-S)" );
     msg_Raw( NULL, "  -n --frontend-number <frontend number>" );
     msg_Raw( NULL, "  -p --force-pulse      force 22kHz pulses for high-band selection (DVB-S)" );
     msg_Raw( NULL, "  -P --pilot            DVB-S2 Pilot (-1 auto, 0 off, 1 on)" );
-- 
2.15.1

-------------- next part --------------
From 057153f110dee1bcbd76a225d10e59ac5b249a25 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sat, 13 Jan 2018 17:59:24 +0200
Subject: [PATCH 2/9] Show TURBO_FEC flag if it's supported by the frontend

---
 dvb.c        | 2 ++
 dvblastctl.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/dvb.c b/dvb.c
index 31276b0..e07cdc5 100644
--- a/dvb.c
+++ b/dvb.c
@@ -52,6 +52,7 @@
 #if DVBAPI_VERSION < 508
   #define DTV_STREAM_ID        42
   #define FE_CAN_MULTISTREAM   0x4000000
+  #define FE_CAN_TURBO_FEC     0x8000000
 #endif
 
 #define MAX_DELIVERY_SYSTEMS 20
@@ -809,6 +810,7 @@ static void FrontendInfo( struct dvb_frontend_info *info, uint32_t version,
     FRONTEND_INFO( info->caps, FE_CAN_2G_MODULATION, "2G_MODULATION" )
 #endif
     FRONTEND_INFO( info->caps, FE_CAN_MULTISTREAM, "MULTISTREAM" )
+    FRONTEND_INFO( info->caps, FE_CAN_TURBO_FEC, "TURBO_FEC" )
     FRONTEND_INFO( info->caps, FE_NEEDS_BENDING, "NEEDS_BENDING" )
     FRONTEND_INFO( info->caps, FE_CAN_RECOVER, "FE_CAN_RECOVER" )
     FRONTEND_INFO( info->caps, FE_CAN_MUTE_TS, "FE_CAN_MUTE_TS" )
diff --git a/dvblastctl.c b/dvblastctl.c
index 378cb47..4137e1f 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -689,6 +689,7 @@ int main( int i_argc, char **ppsz_argv )
         PRINT_CAPS( CAN_2G_MODULATION );
 #endif
 #if DVBAPI_VERSION >= 508
+        PRINT_CAPS( CAN_TURBO_FEC );
         PRINT_CAPS( CAN_MULTISTREAM );
 #endif
 #undef PRINT_CAPS
-- 
2.15.1

-------------- next part --------------
From e9599a803464df2865c5621f2adb03510ec85c67 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sun, 19 Nov 2017 17:04:40 +0200
Subject: [PATCH 3/9] demux: Do not log EIT tables by default

They carry a lot of information and the log is filled up rapidly.
---
 demux.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/demux.c b/demux.c
index aa3dabc..b4f2814 100644
--- a/demux.c
+++ b/demux.c
@@ -3027,7 +3027,6 @@ static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
     free(p_sid->pp_eit_sections[i_section]);
     p_sid->pp_eit_sections[i_section] = p_eit;
 
-    eit_print( p_eit, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT );
     if ( b_print_enabled )
     {
         eit_print( p_eit, demux_Print, NULL,
-- 
2.15.1

-------------- next part --------------
From 86ff46721fed1621e9f894d2cf27b8b919c30a37 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sun, 15 Oct 2017 19:45:46 +0300
Subject: [PATCH 4/9] demux: Track each EIT PSI table separately

This stops sections from one table to overwrite sections in
another table (usually seen with section 0 from EIT/pf and EIT/schedule).

This increases memory usage by at least 32 kb per service
but allows extracting of complete EIT data.
---
 demux.c | 65 +++++++++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 45 insertions(+), 20 deletions(-)

diff --git a/demux.c b/demux.c
index b4f2814..c32ae9c 100644
--- a/demux.c
+++ b/demux.c
@@ -82,11 +82,19 @@ typedef struct ts_pid_t
     struct ev_timer timeout_watcher;
 } ts_pid_t;
 
+struct eit_sections {
+    PSI_TABLE_DECLARE(data);
+};
+
+/* EIT is carried in several separate tables, we need to track each table
+   separately, otherwise one table overwrites sections of another table */
+#define MAX_EIT_TABLES ( EIT_TABLE_ID_SCHED_ACTUAL_LAST - EIT_TABLE_ID_PF_ACTUAL )
+
 typedef struct sid_t
 {
     uint16_t i_sid, i_pmt_pid;
     uint8_t *p_current_pmt;
-    PSI_TABLE_DECLARE(pp_eit_sections);
+    struct eit_sections eit_table[MAX_EIT_TABLES];
 } sid_t;
 
 mtime_t i_wallclock = 0;
@@ -440,7 +448,7 @@ void demux_Open( void )
  *****************************************************************************/
 void demux_Close( void )
 {
-    int i;
+    int i, r;
 
     psi_table_free( pp_current_pat_sections );
     psi_table_free( pp_next_pat_sections );
@@ -461,7 +469,9 @@ void demux_Close( void )
     for ( i = 0; i < i_nb_sids; i++ )
     {
         sid_t *p_sid = pp_sids[i];
-        psi_table_free(p_sid->pp_eit_sections);
+        for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
+            psi_table_free( p_sid->eit_table[r].data );
+        }
         free( p_sid->p_current_pmt );
         free( p_sid );
     }
@@ -1414,11 +1424,17 @@ static void SendSDT( mtime_t i_dts )
 /*****************************************************************************
  * SendEIT
  *****************************************************************************/
+static bool handle_epg( int i_table_id )
+{
+    return (i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
+       (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
+        i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST));
+}
+
 static void SendEIT( sid_t *p_sid, mtime_t i_dts, uint8_t *p_eit )
 {
     uint8_t i_table_id = psi_get_tableid( p_eit );
-    bool b_epg = i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
-                 i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST;
+    bool b_epg = handle_epg( i_table_id );
     uint16_t i_onid = eit_get_onid(p_eit);
     int i;
 
@@ -2170,8 +2186,13 @@ static void DeleteProgram( uint16_t i_sid, uint16_t i_pid )
     }
     p_sid->i_sid = 0;
     p_sid->i_pmt_pid = 0;
-    psi_table_free(p_sid->pp_eit_sections);
-    psi_table_init(p_sid->pp_eit_sections);
+
+    uint8_t r;
+    for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
+        psi_table_free( p_sid->eit_table[r].data );
+        psi_table_init( p_sid->eit_table[r].data );
+    }
+
 }
 
 /*****************************************************************************
@@ -2262,7 +2283,7 @@ static void HandlePAT( mtime_t i_dts )
     bool b_change = false;
     PSI_TABLE_DECLARE( pp_old_pat_sections );
     uint8_t i_last_section = psi_table_get_lastsection( pp_next_pat_sections );
-    uint8_t i;
+    uint8_t i, r;
 
     if ( psi_table_validate( pp_current_pat_sections ) &&
          psi_table_compare( pp_current_pat_sections, pp_next_pat_sections ) )
@@ -2346,7 +2367,9 @@ static void HandlePAT( mtime_t i_dts )
                 {
                     p_sid = malloc( sizeof(sid_t) );
                     p_sid->p_current_pmt = NULL;
-                    psi_table_init(p_sid->pp_eit_sections);
+                    for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
+                        psi_table_init( p_sid->eit_table[r].data );
+                    }
                     i_nb_sids++;
                     pp_sids = realloc( pp_sids, sizeof(sid_t *) * i_nb_sids );
                     pp_sids[i_nb_sids - 1] = p_sid;
@@ -3009,23 +3032,27 @@ static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
         return;
     }
 
-    if ( i_table_id != EIT_TABLE_ID_PF_ACTUAL )
+    bool b_epg = handle_epg( i_table_id );
+    if ( ! b_epg )
         goto out_eit;
 
     /* We do not use psi_table_* primitives as the spec allows for holes in
      * section numbering, and there is no sure way to know whether you have
      * gathered all sections. */
     uint8_t i_section = psi_get_section(p_eit);
-    if (p_sid->pp_eit_sections[i_section] != NULL &&
-        psi_compare(p_sid->pp_eit_sections[i_section], p_eit)) {
+    uint8_t eit_table_id = i_table_id - EIT_TABLE_ID_PF_ACTUAL;
+    if (eit_table_id >= MAX_EIT_TABLES)
+        goto out_eit;
+    if (p_sid->eit_table[eit_table_id].data[i_section] != NULL &&
+        psi_compare(p_sid->eit_table[eit_table_id].data[i_section], p_eit)) {
         /* Identical section. Shortcut. */
-        free(p_sid->pp_eit_sections[i_section]);
-        p_sid->pp_eit_sections[i_section] = p_eit;
+        free(p_sid->eit_table[eit_table_id].data[i_section]);
+        p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
         goto out_eit;
     }
 
-    free(p_sid->pp_eit_sections[i_section]);
-    p_sid->pp_eit_sections[i_section] = p_eit;
+    free(p_sid->eit_table[eit_table_id].data[i_section]);
+    p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
 
     if ( b_print_enabled )
     {
@@ -3037,7 +3064,7 @@ static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
 
 out_eit:
     SendEIT( p_sid, i_dts, p_eit );
-    if ( i_table_id != EIT_TABLE_ID_PF_ACTUAL )
+    if ( ! b_epg )
         free( p_eit );
 }
 
@@ -3096,9 +3123,7 @@ static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
         break;
 
     default:
-        if ( i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
-             (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
-              i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST) )
+        if ( handle_epg( i_table_id ) )
         {
             HandleEIT( i_pid, p_section, i_dts );
             break;
-- 
2.15.1

-------------- next part --------------
From c6ccc522b6ae8d03020354fb07df6c4224d964c0 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sun, 19 Nov 2017 17:03:35 +0200
Subject: [PATCH 5/9] dvblastctl: Add support for getting EIT
 present/following/schedule for chosen service

New 'dvblastctl' commands:

  dvblastctl get_eit_pf <service_id>         - Print EIT present/following events and descriptors.
  dvblastctl get_eit_schedule <service_id>   - Print EIT schedule events and descriptors.
---
 NEWS         |   5 +++
 comm.c       |  14 ++++++-
 comm.h       |   6 ++-
 demux.c      |  55 ++++++++++++++++++++++++++
 dvblast.h    |   2 +
 dvblastctl.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 202 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 8a0b979..92b3926 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Changes between 3.2 and -next
+-----------------------------
+  * Add support for getting EIT present/following for chosen service in dvblastctl
+  * Add support for getting EIT schedule for chosen service in dvblastctl
+
 Changes between 3.1 and 3.2:
 ----------------------------
   * Fix HEVC support
diff --git a/comm.c b/comm.c
index f75f566..8f353a3 100644
--- a/comm.c
+++ b/comm.c
@@ -224,6 +224,8 @@ static void comm_Read(struct ev_loop *loop, struct ev_io *w, int revents)
         break;
     }
 
+    case CMD_GET_EIT_PF:
+    case CMD_GET_EIT_SCHEDULE:
     case CMD_GET_PMT:
     {
         if ( i_size < COMM_HEADER_SIZE + 2 )
@@ -233,11 +235,19 @@ static void comm_Read(struct ev_loop *loop, struct ev_io *w, int revents)
         }
 
         uint16_t i_sid = (uint16_t)((p_input[0] << 8) | p_input[1]);
-        p_packed_section = demux_get_packed_PMT(i_sid, &i_packed_section_size);
+        if ( i_command == CMD_GET_EIT_PF ) {
+            i_answer = RET_EIT_PF;
+            p_packed_section = demux_get_packed_EIT_pf( i_sid, &i_packed_section_size );
+        } else if ( i_command == CMD_GET_EIT_SCHEDULE ) {
+            i_answer = RET_EIT_SCHEDULE;
+            p_packed_section = demux_get_packed_EIT_schedule( i_sid, &i_packed_section_size );
+        } else {
+            i_answer = RET_PMT;
+            p_packed_section = demux_get_packed_PMT(i_sid, &i_packed_section_size);
+        }
 
         if ( p_packed_section && i_packed_section_size )
         {
-            i_answer = RET_PMT;
             i_answer_size = i_packed_section_size;
             memcpy( p_answer + COMM_HEADER_SIZE, p_packed_section, i_packed_section_size );
             free( p_packed_section );
diff --git a/comm.h b/comm.h
index fe58e3e..3cf97e2 100644
--- a/comm.h
+++ b/comm.h
@@ -23,7 +23,7 @@
 #include <bitstream/mpeg/psi.h>
 
 #define COMM_HEADER_SIZE 8
-#define COMM_BUFFER_SIZE (COMM_HEADER_SIZE + ((PSI_PRIVATE_MAX_SIZE + PSI_HEADER_SIZE) * (PSI_TABLE_MAX_SECTIONS / 2)))
+#define COMM_BUFFER_SIZE (COMM_HEADER_SIZE + ((PSI_PRIVATE_MAX_SIZE + PSI_HEADER_SIZE) * PSI_TABLE_MAX_SECTIONS))
 #define COMM_HEADER_MAGIC 0x49
 
 #define COMM_MAX_MSG_CHUNK 4096
@@ -47,6 +47,8 @@ typedef enum {
     CMD_GET_PID             = 16, /* arg: pid (uint16_t) */
     CMD_MMI_SEND_TEXT       = 17, /* arg: slot, en50221_mmi_object_t */
     CMD_MMI_SEND_CHOICE     = 18, /* arg: slot, en50221_mmi_object_t */
+    CMD_GET_EIT_PF          = 19, /* arg: service_id (uint16_t) */
+    CMD_GET_EIT_SCHEDULE    = 20, /* arg: service_id (uint16_t) */
 } ctl_cmd_t;
 
 typedef enum {
@@ -65,6 +67,8 @@ typedef enum {
     RET_PMT                 = 12,
     RET_PIDS                = 13,
     RET_PID                 = 14,
+    RET_EIT_PF              = 15,
+    RET_EIT_SCHEDULE        = 16,
     RET_HUH                 = 255,
 } ctl_cmd_answer_t;
 
diff --git a/demux.c b/demux.c
index c32ae9c..5e9c570 100644
--- a/demux.c
+++ b/demux.c
@@ -3361,6 +3361,61 @@ uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size ) {
     return psi_pack_sections( pp_current_sdt_sections, pi_pack_size );
 }
 
+uint8_t *demux_get_packed_EIT( uint16_t i_sid, uint8_t start_table, uint8_t end_table, unsigned int *eit_size ) {
+    unsigned int i, r;
+
+    *eit_size = 0;
+    sid_t *p_sid = FindSID( i_sid );
+    if ( p_sid == NULL )
+        return NULL;
+
+    /* Calculate eit table size (sum of all sections in all tables between start_start and end_table) */
+    for ( i = start_table; i <= end_table; i++ ) {
+        uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
+        if ( eit_table_idx >= MAX_EIT_TABLES )
+            continue;
+        uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
+        for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
+            uint8_t *p_eit = eit_sections[r];
+            if ( !p_eit )
+                continue;
+            uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
+            *eit_size += psi_length;
+        }
+    }
+
+    uint8_t *p_flat_section = malloc( *eit_size );
+    if ( !p_flat_section )
+        return NULL;
+
+    /* Copy sections */
+    unsigned int i_pos = 0;
+    for ( i = start_table; i <= end_table; i++ ) {
+        uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
+        if ( eit_table_idx >= MAX_EIT_TABLES )
+            continue;
+        uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
+        for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
+            uint8_t *p_eit = eit_sections[r];
+            if ( !p_eit )
+                continue;
+            uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
+            memcpy( p_flat_section + i_pos, p_eit, psi_length );
+            i_pos += psi_length;
+            /* eit_print( p_eit, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT ); */
+        }
+    }
+    return p_flat_section;
+}
+
+uint8_t *demux_get_packed_EIT_pf( uint16_t service_id, unsigned int *pi_pack_size ) {
+    return demux_get_packed_EIT( service_id, EIT_TABLE_ID_PF_ACTUAL, EIT_TABLE_ID_PF_ACTUAL, pi_pack_size );
+}
+
+uint8_t *demux_get_packed_EIT_schedule( uint16_t service_id, unsigned int *pi_pack_size ) {
+    return demux_get_packed_EIT( service_id, EIT_TABLE_ID_SCHED_ACTUAL_FIRST, EIT_TABLE_ID_SCHED_ACTUAL_LAST, pi_pack_size );
+}
+
 uint8_t *demux_get_packed_PMT( uint16_t i_sid, unsigned int *pi_pack_size ) {
     sid_t *p_sid = FindSID( i_sid );
     if ( p_sid != NULL && p_sid->p_current_pmt && pmt_validate( p_sid->p_current_pmt ) )
diff --git a/dvblast.h b/dvblast.h
index a8d51e2..8434880 100644
--- a/dvblast.h
+++ b/dvblast.h
@@ -342,6 +342,8 @@ uint8_t *demux_get_current_packed_CAT( unsigned int *pi_pack_size );
 uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size );
 uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size );
 uint8_t *demux_get_packed_PMT( uint16_t service_id, unsigned int *pi_pack_size );
+uint8_t *demux_get_packed_EIT_pf( uint16_t service_id, unsigned int *pi_pack_size );
+uint8_t *demux_get_packed_EIT_schedule( uint16_t service_id, unsigned int *pi_pack_size );
 void demux_get_PID_info( uint16_t i_pid, uint8_t *p_data );
 void demux_get_PIDS_info( uint8_t *p_data );
 
diff --git a/dvblastctl.c b/dvblastctl.c
index 4137e1f..d1386e8 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -210,6 +210,114 @@ void print_pids( uint8_t *p_data )
     print_pids_footer();
 }
 
+void print_eit_events(uint8_t *p_eit, f_print pf_print, void *print_opaque, f_iconv pf_iconv, void *iconv_opaque, print_type_t i_print_type)
+{
+    uint8_t *p_event;
+    uint8_t j = 0;
+    while ((p_event = eit_get_event(p_eit, j)) != NULL) {
+        j++;
+        char start_str[24], duration_str[10];
+        int duration, hour, min, sec;
+        time_t start_ts;
+
+        start_ts = dvb_time_format_UTC(eitn_get_start_time(p_event), NULL, start_str);
+
+        dvb_time_decode_bcd(eitn_get_duration_bcd(p_event), &duration, &hour, &min, &sec);
+        sprintf(duration_str, "%02d:%02d:%02d", hour, min, sec);
+
+        switch (i_print_type) {
+        case PRINT_XML:
+            pf_print(print_opaque, "<EVENT id=\"%u\" start_time=\"%ld\" start_time_dec=\"%s\""
+                                   " duration=\"%u\" duration_dec=\"%s\""
+                                   " running=\"%d\" free_CA=\"%d\">",
+                     eitn_get_event_id(p_event),
+                     start_ts, start_str,
+                     duration, duration_str,
+                     eitn_get_running(p_event),
+                     eitn_get_ca(p_event)
+                    );
+            break;
+        default:
+            pf_print(print_opaque, "  * EVENT id=%u start_time=%ld start_time_dec=\"%s\" duration=%u duration_dec=%s running=%d free_CA=%d",
+                     eitn_get_event_id(p_event),
+                     start_ts, start_str,
+                     duration, duration_str,
+                     eitn_get_running(p_event),
+                     eitn_get_ca(p_event)
+                    );
+        }
+
+        descs_print(eitn_get_descs(p_event), pf_print, print_opaque,
+                    pf_iconv, iconv_opaque, i_print_type);
+
+        switch (i_print_type) {
+        case PRINT_XML:
+            pf_print(print_opaque, "</EVENT>");
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+void print_eit(uint8_t *p_eit, unsigned int i_eit_size, f_print pf_print, void *print_opaque, f_iconv pf_iconv, void *iconv_opaque, print_type_t i_print_type)
+{
+    uint8_t *p_eit_end = p_eit + i_eit_size;
+    uint8_t i_tid = psi_get_tableid(p_eit);
+    const char *psz_tid = "unknown";
+
+    if (i_tid == EIT_TABLE_ID_PF_ACTUAL)
+        psz_tid = "actual_pf";
+    else if (i_tid == EIT_TABLE_ID_PF_OTHER)
+        psz_tid = "other_pf";
+    else if (i_tid >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST && i_tid <= EIT_TABLE_ID_SCHED_ACTUAL_LAST)
+        psz_tid = "actual_schedule";
+    else if (i_tid >= EIT_TABLE_ID_SCHED_OTHER_FIRST && i_tid <= EIT_TABLE_ID_SCHED_OTHER_LAST)
+        psz_tid = "other_schedule";
+
+    switch (i_print_type) {
+    case PRINT_XML:
+        pf_print(print_opaque,
+                "<EIT tableid=\"0x%02x\" type=\"%s\" service_id=\"%u\""
+                " version=\"%u\""
+                " current_next=\"%u\""
+                " tsid=\"%u\" onid=\"%u\">",
+                 i_tid, psz_tid,
+                 eit_get_sid(p_eit),
+                 psi_get_version(p_eit),
+                 !psi_get_current(p_eit) ? 0 : 1,
+                 eit_get_tsid(p_eit),
+                 eit_get_onid(p_eit)
+                );
+        break;
+    default:
+        pf_print(print_opaque,
+                 "new EIT tableid=0x%02x type=%s service_id=%u version=%u%s"
+                 " tsid=%u"
+                 " onid=%u",
+                 i_tid, psz_tid,
+                 eit_get_sid(p_eit),
+                 psi_get_version(p_eit),
+                 !psi_get_current(p_eit) ? " (next)" : "",
+                 eit_get_tsid(p_eit),
+                 eit_get_onid(p_eit)
+                );
+    }
+
+    while (p_eit < p_eit_end) {
+        print_eit_events(p_eit, pf_print, print_opaque, pf_iconv, iconv_opaque, i_print_type);
+        p_eit += psi_get_length( p_eit ) + PSI_HEADER_SIZE;
+    }
+
+    switch (i_print_type) {
+    case PRINT_XML:
+        pf_print(print_opaque, "</EIT>");
+        break;
+    default:
+        pf_print(print_opaque, "end EIT");
+    }
+}
+
 struct dvblastctl_option {
     char *      opt;
     int         nparams;
@@ -235,6 +343,8 @@ static const struct dvblastctl_option options[] =
     { "get_cat",            0, CMD_GET_CAT },
     { "get_nit",            0, CMD_GET_NIT },
     { "get_sdt",            0, CMD_GET_SDT },
+    { "get_eit_pf",         1, CMD_GET_EIT_PF }, /* arg: service_id (uint16_t) */
+    { "get_eit_schedule",   1, CMD_GET_EIT_SCHEDULE }, /* arg: service_id (uint16_t) */
     { "get_pmt",            1, CMD_GET_PMT }, /* arg: service_id (uint16_t) */
     { "get_pids",           0, CMD_GET_PIDS },
     { "get_pid",            1, CMD_GET_PID },  /* arg: pid (uint16_t) */
@@ -269,6 +379,8 @@ void usage()
     printf("  get_cat                         Return last CAT table.\n");
     printf("  get_nit                         Return last NIT table.\n");
     printf("  get_sdt                         Return last SDT table.\n");
+    printf("  get_eit_pf <service_id>         Return last EIT present/following data.\n");
+    printf("  get_eit_schedule <service_id>   Return last EIT schedule data.\n");
     printf("  get_pmt <service_id>            Return last PMT table.\n");
     printf("  get_pids                        Return info about all pids.\n");
     printf("  get_pid <pid>                   Return info for chosen pid only.\n");
@@ -417,6 +529,8 @@ int main( int i_argc, char **ppsz_argv )
     case CMD_GET_PIDS:
         /* These commands need no special handling because they have no parameters */
         break;
+    case CMD_GET_EIT_PF:
+    case CMD_GET_EIT_SCHEDULE:
     case CMD_GET_PMT:
     {
         uint16_t i_sid = atoi(p_arg1);
@@ -567,6 +681,15 @@ int main( int i_argc, char **ppsz_argv )
         break;
     }
 
+    case RET_EIT_PF:
+    case RET_EIT_SCHEDULE:
+    {
+        uint8_t *p_eit_data = p_buffer + COMM_HEADER_SIZE;
+        unsigned int i_eit_data_size = i_received - COMM_HEADER_SIZE;
+        print_eit( p_eit_data, i_eit_data_size, psi_print, NULL, psi_iconv, NULL, i_print_type );
+        break;
+    }
+
     case RET_PMT:
     {
         pmt_print( p_data, psi_print, NULL, psi_iconv, NULL, i_print_type );
-- 
2.15.1

-------------- next part --------------
From d978ad610df09964d65d8d8746a569bcc56d13c6 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sat, 13 Jan 2018 09:35:41 +0200
Subject: [PATCH 6/9] Remove invalid UTF-8 characters from text output

Sometimes broadcasters put "strange" characters in DVB strings and
when the strings are converted to UTF-8 the output contains
invalid characters.

In order to avoid this problem, this commit instructs iconv
library to ignore characters that can not be converted to
UTF-8 by adding switching the default output charset from
UTF-8 to UTF-8//IGNORE to the output charset.
---
 NEWS         | 1 +
 dvblast.c    | 8 ++++----
 dvblastctl.c | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 92b3926..d6da445 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ Changes between 3.2 and -next
 -----------------------------
   * Add support for getting EIT present/following for chosen service in dvblastctl
   * Add support for getting EIT schedule for chosen service in dvblastctl
+  * Switch default string charset to UTF-8//IGNORE
 
 Changes between 3.1 and 3.2:
 ----------------------------
diff --git a/dvblast.c b/dvblast.c
index e0403f7..8424d05 100644
--- a/dvblast.c
+++ b/dvblast.c
@@ -92,7 +92,7 @@ int b_select_pmts = 0;
 int b_random_tsid = 0;
 char *psz_udp_src = NULL;
 int i_asi_adapter = 0;
-const char *psz_native_charset = "UTF-8";
+const char *psz_native_charset = "UTF-8//IGNORE";
 print_type_t i_print_type = PRINT_TEXT;
 bool b_print_enabled = false;
 FILE *print_fh;
@@ -114,7 +114,7 @@ static mtime_t i_latency_global = DEFAULT_OUTPUT_LATENCY;
 static mtime_t i_retention_global = DEFAULT_MAX_RETENTION;
 static int i_ttl_global = 64;
 
-static const char *psz_dvb_charset = "UTF-8";
+static const char *psz_dvb_charset = "UTF-8//IGNORE";
 static iconv_t conf_iconv = (iconv_t)-1;
 static uint16_t i_network_id = 0xffff;
 static dvb_string_t network_name;
@@ -697,8 +697,8 @@ void usage()
     msg_Raw( NULL, "Misc:" );
     msg_Raw( NULL, "  -h --help             display this full help" );
     msg_Raw( NULL, "  -i --priority <RT priority>" );
-    msg_Raw( NULL, "  -j --system-charset   character set used for printing messages (default UTF-8)" );
-    msg_Raw( NULL, "  -J --dvb-charset      character set used in output DVB tables (default UTF-8)" );
+    msg_Raw( NULL, "  -j --system-charset   character set used for printing messages (default UTF-8//IGNORE)" );
+    msg_Raw( NULL, "  -J --dvb-charset      character set used in output DVB tables (default UTF-8//IGNORE)" );
     msg_Raw( NULL, "  -l --logger           use syslog for logging messages instead of stderr" );
     msg_Raw( NULL, "  -g --logger-ident     program name that will be used in syslog messages" );
     msg_Raw( NULL, "  -x --print            print interesting events on stdout in a given format" );
diff --git a/dvblastctl.c b/dvblastctl.c
index d1386e8..62a379c 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -116,7 +116,7 @@ static char *iconv_append_null(const char *p_string, size_t i_length)
     return psz_string;
 }
 
-const char *psz_native_charset = "UTF-8";
+const char *psz_native_charset = "UTF-8//IGNORE";
 
 char *psi_iconv(void *_unused, const char *psz_encoding,
                   char *p_string, size_t i_length)
-- 
2.15.1

-------------- next part --------------
From 3b72e9adf913eb08364a1852f804334b7b40eef9 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sat, 13 Jan 2018 09:47:29 +0200
Subject: [PATCH 7/9] dvblastctl: Add --system-charset/-j option

---
 NEWS         | 1 +
 dvblastctl.c | 8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index d6da445..3d30ba0 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Changes between 3.2 and -next
   * Add support for getting EIT present/following for chosen service in dvblastctl
   * Add support for getting EIT schedule for chosen service in dvblastctl
   * Switch default string charset to UTF-8//IGNORE
+  * Add --system-charset/-j option to dvblastctl
 
 Changes between 3.1 and 3.2:
 ----------------------------
diff --git a/dvblastctl.c b/dvblastctl.c
index 62a379c..cf88027 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -358,6 +358,7 @@ void usage()
     printf("Usage: dvblastctl -r <remote socket> [-x <text|xml>] [cmd]\n");
     printf("Options:\n");
     printf("  -r --remote-socket <name>       Set socket name to <name>.\n" );
+    printf("  -j --system-charset <name>      Character set used for output (default UTF-8//IGNORE)\n" );
     printf("  -x --print <text|xml>           Choose output format for info commands.\n" );
     printf("Control commands:\n");
     printf("  reload                          Reload configuration.\n");
@@ -408,12 +409,13 @@ int main( int i_argc, char **ppsz_argv )
         static const struct option long_options[] =
         {
             {"remote-socket", required_argument, NULL, 'r'},
+            {"system-charset", required_argument, NULL, 'j'},
             {"print", required_argument, NULL, 'x'},
             {"help", no_argument, NULL, 'h'},
             {0, 0, 0, 0}
         };
 
-        if ( (c = getopt_long(i_argc, ppsz_argv, "r:x:h", long_options, NULL)) == -1 )
+        if ( (c = getopt_long(i_argc, ppsz_argv, "r:x:j:h", long_options, NULL)) == -1 )
             break;
 
         switch ( c )
@@ -422,6 +424,10 @@ int main( int i_argc, char **ppsz_argv )
             psz_srv_socket = optarg;
             break;
 
+        case 'j':
+            psz_native_charset = optarg;
+            break;
+
         case 'x':
             if ( !strcmp(optarg, "text") )
                 i_print_type = PRINT_TEXT;
-- 
2.15.1

-------------- next part --------------
From e75a953b5262b2ea99c244543236571c6d67ba20 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sat, 13 Jan 2018 19:02:48 +0200
Subject: [PATCH 8/9] dvblastctl: Add --timeout/-t option and set default to 15
 seconds.

It is possible that 'dvblast' does not answer on the command socket
and in this case 'dvblastctl' just hangs waiting forever.

This commit introduces timeout for send/receive operations in dvblastctl.
The timeout is set in seconds and the default value is 15 seconds.
---
 NEWS         |  1 +
 dvblastctl.c | 21 ++++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 3d30ba0..9b175fa 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Changes between 3.2 and -next
   * Add support for getting EIT schedule for chosen service in dvblastctl
   * Switch default string charset to UTF-8//IGNORE
   * Add --system-charset/-j option to dvblastctl
+  * Add --timeout/-t option to dvblastctl and set default to 15 seconds
 
 Changes between 3.1 and 3.2:
 ----------------------------
diff --git a/dvblastctl.c b/dvblastctl.c
index cf88027..37d96e8 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -51,6 +51,7 @@
 
 int i_verbose = 3;
 int i_syslog = 0;
+unsigned int i_timeout_seconds = 15;
 
 print_type_t i_print_type = PRINT_TEXT;
 mtime_t now;
@@ -358,6 +359,7 @@ void usage()
     printf("Usage: dvblastctl -r <remote socket> [-x <text|xml>] [cmd]\n");
     printf("Options:\n");
     printf("  -r --remote-socket <name>       Set socket name to <name>.\n" );
+    printf("  -t --timeout <seconds>          Set socket read/write timeout in seconds (default 15).\n" );
     printf("  -j --system-charset <name>      Character set used for output (default UTF-8//IGNORE)\n" );
     printf("  -x --print <text|xml>           Choose output format for info commands.\n" );
     printf("Control commands:\n");
@@ -409,13 +411,14 @@ int main( int i_argc, char **ppsz_argv )
         static const struct option long_options[] =
         {
             {"remote-socket", required_argument, NULL, 'r'},
+            {"timeout", required_argument, NULL, 't'},
             {"system-charset", required_argument, NULL, 'j'},
             {"print", required_argument, NULL, 'x'},
             {"help", no_argument, NULL, 'h'},
             {0, 0, 0, 0}
         };
 
-        if ( (c = getopt_long(i_argc, ppsz_argv, "r:x:j:h", long_options, NULL)) == -1 )
+        if ( (c = getopt_long(i_argc, ppsz_argv, "r:t:x:j:h", long_options, NULL)) == -1 )
             break;
 
         switch ( c )
@@ -424,6 +427,10 @@ int main( int i_argc, char **ppsz_argv )
             psz_srv_socket = optarg;
             break;
 
+        case 't':
+            i_timeout_seconds = (unsigned int)strtoul(optarg, NULL, 10);
+            break;
+
         case 'j':
             psz_native_charset = optarg;
             break;
@@ -606,6 +613,18 @@ int main( int i_argc, char **ppsz_argv )
         return_error( "Unhandled option (%d)", opt.cmd );
     }
 
+    if ( i_timeout_seconds > 0 ) {
+        struct timeval tv_timeout = {
+            .tv_sec  = i_timeout_seconds,
+            .tv_usec = 0,
+        };
+        if ( setsockopt( i_fd, SOL_SOCKET, SO_SNDTIMEO, &tv_timeout, sizeof( tv_timeout ) ) != 0 )
+            return_error( "Cannot set SO_SNDTIMEO (%s)", strerror(errno) );
+
+        if ( setsockopt( i_fd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof( tv_timeout ) ) != 0 )
+            return_error( "Cannot set SO_RCVTIMEO (%s)", strerror(errno) );
+    }
+
     /* Send command and receive answer */
     if ( sendto( i_fd, p_buffer, i_size, 0, (struct sockaddr *)&sun_server,
                  SUN_LEN(&sun_server) ) < 0 )
-- 
2.15.1

-------------- next part --------------
From db8cf1ea9447438757cb91e8b626dd201a2f44f0 Mon Sep 17 00:00:00 2001
From: Georgi Chorbadzhiyski <gf at unixsol.org>
Date: Sat, 13 Jan 2018 20:30:54 +0200
Subject: [PATCH 9/9] Add --lnb-type option to dvblast

Setting --lnb-type old-sky allows dvblast to work with some
Australian satellite services.
---
 NEWS      |  1 +
 dvb.c     | 93 ++++++++++++++++++++++++++++++++++++++++-----------------------
 dvblast.1 |  3 +++
 dvblast.c | 10 ++++++-
 dvblast.h |  1 +
 5 files changed, 73 insertions(+), 35 deletions(-)

diff --git a/NEWS b/NEWS
index 9b175fa..647e3f5 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Changes between 3.2 and -next
   * Switch default string charset to UTF-8//IGNORE
   * Add --system-charset/-j option to dvblastctl
   * Add --timeout/-t option to dvblastctl and set default to 15 seconds
+  * Add --lnb-type universal|old-sky option to dvblast
 
 Changes between 3.1 and 3.2:
 ----------------------------
diff --git a/dvb.c b/dvb.c
index e07cdc5..3dd9289 100644
--- a/dvb.c
+++ b/dvb.c
@@ -471,44 +471,69 @@ static int FrontendDoDiseqc(void)
 
     fe_tone = b_tone ? SEC_TONE_ON : SEC_TONE_OFF;
 
-    /* Automatic mode. */
-    if ( i_frequency >= 950000 && i_frequency <= 2150000 )
+    if ( strcmp( psz_lnb_type, "universal" ) == 0 )
     {
-        msg_Dbg( NULL, "frequency %d is in IF-band", i_frequency );
-        bis_frequency = i_frequency;
-    }
-    else if ( i_frequency >= 2500000 && i_frequency <= 2700000 )
-    {
-        msg_Dbg( NULL, "frequency %d is in S-band", i_frequency );
-        bis_frequency = 3650000 - i_frequency;
-    }
-    else if ( i_frequency >= 3400000 && i_frequency <= 4200000 )
-    {
-        msg_Dbg( NULL, "frequency %d is in C-band (lower)", i_frequency );
-        bis_frequency = 5150000 - i_frequency;
-    }
-    else if ( i_frequency >= 4500000 && i_frequency <= 4800000 )
-    {
-        msg_Dbg( NULL, "frequency %d is in C-band (higher)", i_frequency );
-        bis_frequency = 5950000 - i_frequency;
-    }
-    else if ( i_frequency >= 10700000 && i_frequency < 11700000 )
-    {
-        msg_Dbg( NULL, "frequency %d is in Ku-band (lower)",
-                 i_frequency );
-        bis_frequency = i_frequency - 9750000;
+        /* Automatic mode. */
+        if ( i_frequency >= 950000 && i_frequency <= 2150000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in IF-band", i_frequency );
+            bis_frequency = i_frequency;
+        }
+        else if ( i_frequency >= 2500000 && i_frequency <= 2700000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in S-band", i_frequency );
+            bis_frequency = 3650000 - i_frequency;
+        }
+        else if ( i_frequency >= 3400000 && i_frequency <= 4200000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in C-band (lower)", i_frequency );
+            bis_frequency = 5150000 - i_frequency;
+        }
+        else if ( i_frequency >= 4500000 && i_frequency <= 4800000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in C-band (higher)", i_frequency );
+            bis_frequency = 5950000 - i_frequency;
+        }
+        else if ( i_frequency >= 10700000 && i_frequency < 11700000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in Ku-band (lower)",
+                     i_frequency );
+            bis_frequency = i_frequency - 9750000;
+        }
+        else if ( i_frequency >= 11700000 && i_frequency <= 13250000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in Ku-band (higher)",
+                     i_frequency );
+            bis_frequency = i_frequency - 10600000;
+            fe_tone = SEC_TONE_ON;
+        }
+        else
+        {
+            msg_Err( NULL, "frequency %d is out of any known band",
+                     i_frequency );
+            exit(1);
+        }
     }
-    else if ( i_frequency >= 11700000 && i_frequency <= 13250000 )
+    else if ( strcmp( psz_lnb_type, "old-sky" ) == 0 )
     {
-        msg_Dbg( NULL, "frequency %d is in Ku-band (higher)",
-                 i_frequency );
-        bis_frequency = i_frequency - 10600000;
-        fe_tone = SEC_TONE_ON;
+         if ( i_frequency >= 11700000 && i_frequency <= 13250000 )
+        {
+            msg_Dbg( NULL, "frequency %d is in Ku-band (higher)",
+                     i_frequency );
+            bis_frequency = i_frequency - 11300000;
+            fe_tone = SEC_TONE_ON;
+        }
+        else
+        {
+            msg_Err( NULL, "frequency %d is out of any known band",
+                     i_frequency );
+            exit(1);
+        }
     }
     else
     {
-        msg_Err( NULL, "frequency %d is out of any known band",
-                 i_frequency );
+        msg_Err( NULL, "lnb-type '%s' is not known. Valid type: universal old-sky",
+                 psz_lnb_type );
         exit(1);
     }
 
@@ -609,8 +634,8 @@ static int FrontendDoDiseqc(void)
 
     msleep(100000); /* ... */
 
-    msg_Dbg( NULL, "configuring LNB to v=%d p=%d satnum=%x uncommitted=%x",
-             i_voltage, b_tone, i_satnum, i_uncommitted );
+    msg_Dbg( NULL, "configuring LNB to v=%d p=%d satnum=%x uncommitted=%x lnb-type=%s bis_frequency=%d",
+             i_voltage, b_tone, i_satnum, i_uncommitted, psz_lnb_type, bis_frequency );
     return bis_frequency;
 }
 
diff --git a/dvblast.1 b/dvblast.1
index f9d8212..c8ff4bf 100644
--- a/dvblast.1
+++ b/dvblast.1
@@ -73,6 +73,9 @@ Frontend frequency. If '\-' is specified instead of a numeric value,
 the frontend will be not be tuned by dvblast and you should use external
 tuning tool (szap) to tune it.
 .TP
+\fB\-8\fR, \fB\-\-lnb\-type\fR universal\|old\-sky
+Choose LNB type. Default: 'universal' - Universal LNB ("Astra" LNB)
+.TP
 \fB\-F\fR, \fB\-\-fec\-inner\fR <FEC>
 Forward Error Correction used by satellite (FEC Inner)
 .br
diff --git a/dvblast.c b/dvblast.c
index 8424d05..eebb562 100644
--- a/dvblast.c
+++ b/dvblast.c
@@ -67,6 +67,7 @@ int i_fenum = 0;
 int i_canum = 0;
 char *psz_delsys = NULL;
 int i_frequency = 0;
+char *psz_lnb_type = "universal";
 int dvb_plp_id = 0;
 int i_inversion = -1;
 int i_srate = 27500000;
@@ -644,6 +645,8 @@ void usage()
     msg_Raw( NULL, "  -5 --delsys           delivery system" );
     msg_Raw( NULL, "    DVBS|DVBS2|DVBC_ANNEX_A|DVBT|DVBT2|ATSC|ISDBT|DVBC_ANNEX_B(ATSC-C/QAMB) (default guessed)");
     msg_Raw( NULL, "  -f --frequency        frontend frequency" );
+    msg_Raw( NULL, "  -8 --lnb-type <type>  Set LNB type')" );
+    msg_Raw( NULL, "        universal old-sky (default: universal)");
     msg_Raw( NULL, "  -9 --dvb-plp-id <number> Switch PLP of the DVB-T2 transmission (for Russia special)" );
     msg_Raw( NULL, "  -F --fec-inner        Forward Error Correction (FEC Inner)");
     msg_Raw( NULL, "    DVB-S2 0|12|23|34|35|56|78|89|910|999 (default auto: 999)");
@@ -730,7 +733,7 @@ int main( int i_argc, char **pp_argv )
         usage();
 
     /*
-     * The only short options left are: 48
+     * The only short options left are: 4
      * Use them wisely.
      */
     static const struct option long_options[] =
@@ -745,6 +748,7 @@ int main( int i_argc, char **pp_argv )
         { "delsys",          required_argument, NULL, '5' },
         { "dvb-plp-id",      required_argument, NULL, '9' },
         { "frequency",       required_argument, NULL, 'f' },
+        { "lnb-type",        required_argument, NULL, '8' },
         { "fec-inner",       required_argument, NULL, 'F' },
         { "rolloff",         required_argument, NULL, 'R' },
         { "symbol-rate",     required_argument, NULL, 's' },
@@ -890,6 +894,10 @@ int main( int i_argc, char **pp_argv )
 #endif
             break;
 
+        case '8':
+            psz_lnb_type = optarg;
+            break;
+
         case 'F':
             i_fec = strtol( optarg, NULL, 0 );
             break;
diff --git a/dvblast.h b/dvblast.h
index 8434880..0c5218c 100644
--- a/dvblast.h
+++ b/dvblast.h
@@ -221,6 +221,7 @@ extern int i_canum;
 extern char *psz_delsys;
 extern int i_dvr_buffer_size;
 extern int i_frequency;
+extern char *psz_lnb_type;
 extern int i_srate;
 extern int i_satnum;
 extern int i_uncommitted;
-- 
2.15.1



More information about the dvblast-devel mailing list