[dvblast-devel] [PATCH 12/20] dvblastctl: Add get_pmt command.

Georgi Chorbadzhiyski gf at unixsol.org
Mon Sep 5 09:52:47 CEST 2011


get_pmt command return pmt for chosen service_id or no_data
if the service do not exist.
---
 NEWS         |    1 +
 comm.c       |   26 ++++++++++++++++++++++++++
 comm.h       |    2 ++
 demux.c      |   11 +++++++++++
 dvblast.h    |    2 ++
 dvblastctl.c |   20 ++++++++++++++++++--
 util.c       |   19 +++++++++++++++++++
 7 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 7de4d63..2d65e84 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ Changes between 1.2 and 2.0:
   * Add support for MRTG statistics
   * Add detailed information for TS errors
   * Add support for getting PAT/CAT/NIT/SDT tables in dvblastctl
+  * Add support for getting PMT table for chosen service in dvblastctl
 
 Changes between 1.1 and 1.2:
 ----------------------------
diff --git a/comm.c b/comm.c
index c3f658d..3119690 100644
--- a/comm.c
+++ b/comm.c
@@ -79,6 +79,7 @@ void comm_Read( void )
     uint8_t i_command, i_answer;
     uint8_t *p_packed_section;
     unsigned int i_packed_section_size;
+    uint8_t *p_input = p_buffer + COMM_HEADER_SIZE;
 
     i_size = recvfrom( i_comm_fd, p_buffer, COMM_BUFFER_SIZE, 0,
                        (struct sockaddr *)&sun_client, &sun_length );
@@ -193,6 +194,31 @@ void comm_Read( void )
 
         break;
     }
+
+    case CMD_GET_PMT:
+    {
+        if ( i_size < COMM_HEADER_SIZE + 2 )
+        {
+            msg_Err( NULL, "command packet is too short (%zd)\n", i_size );
+            return;
+        }
+
+        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 ( 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 );
+        } else {
+            i_answer = RET_NODATA;
+        }
+
+        break;
+    }
+
     default:
         msg_Err( NULL, "wrong command %u", i_command );
         i_answer = RET_HUH;
diff --git a/comm.h b/comm.h
index 7bfb6df..45372ef 100644
--- a/comm.h
+++ b/comm.h
@@ -40,6 +40,7 @@
 #define CMD_GET_CAT 11
 #define CMD_GET_NIT 12
 #define CMD_GET_SDT 13
+#define CMD_GET_PMT 14 /* arg: service_id (uint16_t) */
 
 #define RET_OK 0
 #define RET_ERR 1
@@ -53,6 +54,7 @@
 #define RET_CAT 9
 #define RET_NIT 10
 #define RET_SDT 11
+#define RET_PMT 12
 #define RET_HUH 255
 
 struct ret_frontend_status
diff --git a/demux.c b/demux.c
index 1787593..9c1a609 100644
--- a/demux.c
+++ b/demux.c
@@ -2791,3 +2791,14 @@ uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size ) {
 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_PMT( uint16_t i_sid, unsigned int *pi_pack_size ) {
+    int i;
+    for ( i = 0; i < i_nb_sids; i++ ) {
+        sid_t *p_sid = pp_sids[i];
+        if ( p_sid->i_sid && p_sid->i_sid == i_sid && pmt_validate( p_sid->p_current_pmt ) ) {
+            return psi_pack_section( p_sid->p_current_pmt, pi_pack_size );
+        }
+    }
+    return NULL;
+}
diff --git a/dvblast.h b/dvblast.h
index 010ab83..1bfd5ac 100644
--- a/dvblast.h
+++ b/dvblast.h
@@ -206,6 +206,7 @@ void hexDump( uint8_t *p_data, uint32_t i_len );
 struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
                                    uint16_t i_default_port );
 
+uint8_t *psi_pack_section( uint8_t *p_sections, unsigned int *pi_size );
 uint8_t *psi_pack_sections( uint8_t **pp_sections, unsigned int *pi_size );
 uint8_t **psi_unpack_sections( uint8_t *p_flat_sections, unsigned int i_size );
 
@@ -241,6 +242,7 @@ uint8_t *demux_get_current_packed_PAT( unsigned int *pi_pack_size );
 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 );
 
 output_t *output_Create( const output_config_t *p_config );
 int output_Init( output_t *p_output, const output_config_t *p_config );
diff --git a/dvblastctl.c b/dvblastctl.c
index 43c5455..ef2e1aa 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -87,7 +87,7 @@ void usage()
 {
     msg_Raw( NULL, "DVBlastctl %d.%d.%d (%s)", VERSION_MAJOR, VERSION_MINOR,
              VERSION_REVISION, VERSION_EXTRA );
-    msg_Raw( NULL, "Usage: dvblastctl -r <remote socket> reload|shutdown|fe_status|mmi_status|mmi_open|mmi_close|mmi_get|mmi_send_text|mmi_send_choice|get_pat|get_cat|get_nit|get_sdt [<CAM slot>] [-x <text|xml>] [<text/choice>]" );
+    msg_Raw( NULL, "Usage: dvblastctl -r <remote socket> reload|shutdown|fe_status|mmi_status|mmi_open|mmi_close|mmi_get|mmi_send_text|mmi_send_choice|get_pat|get_cat|get_nit|get_sdt|get_pmt [<ServiceID>] [<CAM slot>] [-x <text|xml>] [<text/choice>]" );
     exit(1);
 }
 
@@ -101,6 +101,7 @@ int main( int i_argc, char **ppsz_argv )
     ssize_t i_size;
     struct sockaddr_un sun_client, sun_server;
     uint8_t p_buffer[COMM_BUFFER_SIZE];
+    uint8_t *p_data = p_buffer + COMM_HEADER_SIZE;
 
     for ( ; ; )
     {
@@ -150,6 +151,7 @@ int main( int i_argc, char **ppsz_argv )
           && strcmp(ppsz_argv[optind], "get_cat")
           && strcmp(ppsz_argv[optind], "get_nit")
           && strcmp(ppsz_argv[optind], "get_sdt")
+          && strcmp(ppsz_argv[optind], "get_pmt")
           && strcmp(ppsz_argv[optind], "mmi_status")
           && strcmp(ppsz_argv[optind], "mmi_slot_status")
           && strcmp(ppsz_argv[optind], "mmi_open")
@@ -160,6 +162,7 @@ int main( int i_argc, char **ppsz_argv )
         usage();
 
     if ( (!strcmp(ppsz_argv[optind], "mmi_slot_status")
+           || !strcmp(ppsz_argv[optind], "get_pmt")
            || !strcmp(ppsz_argv[optind], "mmi_open")
            || !strcmp(ppsz_argv[optind], "mmi_close")
            || !strcmp(ppsz_argv[optind], "mmi_get")
@@ -233,7 +236,13 @@ int main( int i_argc, char **ppsz_argv )
         p_buffer[1] = CMD_GET_NIT;
     else if ( !strcmp(ppsz_argv[optind], "get_sdt") )
         p_buffer[1] = CMD_GET_SDT;
-    else if ( !strcmp(ppsz_argv[optind], "mmi_status") )
+    else if ( !strcmp(ppsz_argv[optind], "get_pmt") ) {
+        uint16_t i_sid = atoi(ppsz_argv[optind + 1]);
+        p_buffer[1] = CMD_GET_PMT;
+        i_size = COMM_HEADER_SIZE + 2;
+        p_data[0] = (uint8_t)((i_sid >> 8) & 0xff);
+        p_data[1] = (uint8_t)(i_sid & 0xff);
+    } else if ( !strcmp(ppsz_argv[optind], "mmi_status") )
         p_buffer[1] = CMD_MMI_STATUS;
     else
     {
@@ -379,6 +388,13 @@ int main( int i_argc, char **ppsz_argv )
         break;
     }
 
+    case RET_PMT:
+    {
+        pmt_print( p_data, psi_print, NULL, psi_iconv, NULL, i_print_type );
+        exit(0);
+        break;
+    }
+
     case RET_FRONTEND_STATUS:
     {
         struct ret_frontend_status *p_ret =
diff --git a/util.c b/util.c
index de141ab..26b8389 100644
--- a/util.c
+++ b/util.c
@@ -336,6 +336,25 @@ struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
 }
 
 /*****************************************************************************
+ * psi_pack_section: return psi section
+ *  Note: Allocates the return value. The caller must free it.
+ *****************************************************************************/
+uint8_t *psi_pack_section( uint8_t *p_section, unsigned int *pi_size ) {
+    uint8_t *p_flat_section;
+    uint16_t psi_length = psi_get_length( p_section ) + PSI_HEADER_SIZE;
+    *pi_size = 0;
+
+    p_flat_section = malloc( psi_length );
+    if ( !p_flat_section )
+        return NULL;
+
+    *pi_size = psi_length;
+    memcpy( p_flat_section, p_section, psi_length );
+
+    return p_flat_section;
+}
+
+/*****************************************************************************
  * psi_pack_sections: return psi sections as array
  *  Note: Allocates the return value. The caller must free it.
  *****************************************************************************/
-- 
1.7.5.1



More information about the dvblast-devel mailing list