Commit b54e09b5 authored by Georgi Chorbadzhiyski's avatar Georgi Chorbadzhiyski

dvblastctl: Add get_pmt command.

get_pmt command return pmt for chosen service_id or no_data
if the service do not exist.
parent 906d79c5
...@@ -19,6 +19,7 @@ Changes between 1.2 and 2.0: ...@@ -19,6 +19,7 @@ Changes between 1.2 and 2.0:
* Add support for MRTG statistics * Add support for MRTG statistics
* Add detailed information for TS errors * Add detailed information for TS errors
* Add support for getting PAT/CAT/NIT/SDT tables in dvblastctl * 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: Changes between 1.1 and 1.2:
---------------------------- ----------------------------
......
...@@ -79,6 +79,7 @@ void comm_Read( void ) ...@@ -79,6 +79,7 @@ void comm_Read( void )
uint8_t i_command, i_answer; uint8_t i_command, i_answer;
uint8_t *p_packed_section; uint8_t *p_packed_section;
unsigned int i_packed_section_size; 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, i_size = recvfrom( i_comm_fd, p_buffer, COMM_BUFFER_SIZE, 0,
(struct sockaddr *)&sun_client, &sun_length ); (struct sockaddr *)&sun_client, &sun_length );
...@@ -193,6 +194,31 @@ void comm_Read( void ) ...@@ -193,6 +194,31 @@ void comm_Read( void )
break; 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: default:
msg_Err( NULL, "wrong command %u", i_command ); msg_Err( NULL, "wrong command %u", i_command );
i_answer = RET_HUH; i_answer = RET_HUH;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define CMD_GET_CAT 11 #define CMD_GET_CAT 11
#define CMD_GET_NIT 12 #define CMD_GET_NIT 12
#define CMD_GET_SDT 13 #define CMD_GET_SDT 13
#define CMD_GET_PMT 14 /* arg: service_id (uint16_t) */
#define RET_OK 0 #define RET_OK 0
#define RET_ERR 1 #define RET_ERR 1
...@@ -53,6 +54,7 @@ ...@@ -53,6 +54,7 @@
#define RET_CAT 9 #define RET_CAT 9
#define RET_NIT 10 #define RET_NIT 10
#define RET_SDT 11 #define RET_SDT 11
#define RET_PMT 12
#define RET_HUH 255 #define RET_HUH 255
struct ret_frontend_status struct ret_frontend_status
......
...@@ -2791,3 +2791,14 @@ uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size ) { ...@@ -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 ) { uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size ) {
return psi_pack_sections( pp_current_sdt_sections, 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;
}
...@@ -206,6 +206,7 @@ void hexDump( uint8_t *p_data, uint32_t i_len ); ...@@ -206,6 +206,7 @@ void hexDump( uint8_t *p_data, uint32_t i_len );
struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end, struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
uint16_t i_default_port ); 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_pack_sections( uint8_t **pp_sections, unsigned int *pi_size );
uint8_t **psi_unpack_sections( uint8_t *p_flat_sections, unsigned int i_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 ); ...@@ -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_CAT( unsigned int *pi_pack_size );
uint8_t *demux_get_current_packed_NIT( 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_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 ); output_t *output_Create( const output_config_t *p_config );
int output_Init( output_t *p_output, const output_config_t *p_config ); int output_Init( output_t *p_output, const output_config_t *p_config );
......
...@@ -87,7 +87,7 @@ void usage() ...@@ -87,7 +87,7 @@ void usage()
{ {
msg_Raw( NULL, "DVBlastctl %d.%d.%d (%s)", VERSION_MAJOR, VERSION_MINOR, msg_Raw( NULL, "DVBlastctl %d.%d.%d (%s)", VERSION_MAJOR, VERSION_MINOR,
VERSION_REVISION, VERSION_EXTRA ); 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); exit(1);
} }
...@@ -101,6 +101,7 @@ int main( int i_argc, char **ppsz_argv ) ...@@ -101,6 +101,7 @@ int main( int i_argc, char **ppsz_argv )
ssize_t i_size; ssize_t i_size;
struct sockaddr_un sun_client, sun_server; struct sockaddr_un sun_client, sun_server;
uint8_t p_buffer[COMM_BUFFER_SIZE]; uint8_t p_buffer[COMM_BUFFER_SIZE];
uint8_t *p_data = p_buffer + COMM_HEADER_SIZE;
for ( ; ; ) for ( ; ; )
{ {
...@@ -150,6 +151,7 @@ int main( int i_argc, char **ppsz_argv ) ...@@ -150,6 +151,7 @@ int main( int i_argc, char **ppsz_argv )
&& strcmp(ppsz_argv[optind], "get_cat") && strcmp(ppsz_argv[optind], "get_cat")
&& strcmp(ppsz_argv[optind], "get_nit") && strcmp(ppsz_argv[optind], "get_nit")
&& strcmp(ppsz_argv[optind], "get_sdt") && strcmp(ppsz_argv[optind], "get_sdt")
&& strcmp(ppsz_argv[optind], "get_pmt")
&& strcmp(ppsz_argv[optind], "mmi_status") && strcmp(ppsz_argv[optind], "mmi_status")
&& strcmp(ppsz_argv[optind], "mmi_slot_status") && strcmp(ppsz_argv[optind], "mmi_slot_status")
&& strcmp(ppsz_argv[optind], "mmi_open") && strcmp(ppsz_argv[optind], "mmi_open")
...@@ -160,6 +162,7 @@ int main( int i_argc, char **ppsz_argv ) ...@@ -160,6 +162,7 @@ int main( int i_argc, char **ppsz_argv )
usage(); usage();
if ( (!strcmp(ppsz_argv[optind], "mmi_slot_status") 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_open")
|| !strcmp(ppsz_argv[optind], "mmi_close") || !strcmp(ppsz_argv[optind], "mmi_close")
|| !strcmp(ppsz_argv[optind], "mmi_get") || !strcmp(ppsz_argv[optind], "mmi_get")
...@@ -233,7 +236,13 @@ int main( int i_argc, char **ppsz_argv ) ...@@ -233,7 +236,13 @@ int main( int i_argc, char **ppsz_argv )
p_buffer[1] = CMD_GET_NIT; p_buffer[1] = CMD_GET_NIT;
else if ( !strcmp(ppsz_argv[optind], "get_sdt") ) else if ( !strcmp(ppsz_argv[optind], "get_sdt") )
p_buffer[1] = CMD_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; p_buffer[1] = CMD_MMI_STATUS;
else else
{ {
...@@ -379,6 +388,13 @@ int main( int i_argc, char **ppsz_argv ) ...@@ -379,6 +388,13 @@ int main( int i_argc, char **ppsz_argv )
break; break;
} }
case RET_PMT:
{
pmt_print( p_data, psi_print, NULL, psi_iconv, NULL, i_print_type );
exit(0);
break;
}
case RET_FRONTEND_STATUS: case RET_FRONTEND_STATUS:
{ {
struct ret_frontend_status *p_ret = struct ret_frontend_status *p_ret =
......
...@@ -335,6 +335,25 @@ struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end, ...@@ -335,6 +335,25 @@ struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
return p_res; return p_res;
} }
/*****************************************************************************
* 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 * psi_pack_sections: return psi sections as array
* Note: Allocates the return value. The caller must free it. * Note: Allocates the return value. The caller must free it.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment