1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004, 2015 VideoLAN
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
31 #include <sys/types.h>
32 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
39 #include <bitstream/mpeg/psi.h>
43 /*****************************************************************************
45 *****************************************************************************/
46 #define MAX_BLOCKS 500
53 static block_t
*p_block_lifo
= NULL
;
54 static unsigned int i_block_count
= 0;
56 /*****************************************************************************
58 *****************************************************************************/
59 block_t
*block_New( void )
65 p_block
= p_block_lifo
;
66 p_block_lifo
= p_block
->p_next
;
71 p_block
= malloc(sizeof(block_t
));
74 p_block
->p_next
= NULL
;
75 p_block
->i_refcount
= 1;
79 /*****************************************************************************
81 *****************************************************************************/
82 void block_Delete( block_t
*p_block
)
84 if (i_block_count
>= MAX_BLOCKS
)
90 p_block
->p_next
= p_block_lifo
;
91 p_block_lifo
= p_block
;
95 /*****************************************************************************
97 *****************************************************************************/
98 void block_Vacuum( void )
100 while (i_block_count
)
102 block_t
*p_block
= p_block_lifo
;
103 p_block_lifo
= p_block
->p_next
;
109 /*****************************************************************************
111 *****************************************************************************/
112 void msg_Connect( const char *ident
)
115 openlog( ident
, LOG_NDELAY
| LOG_PID
, LOG_USER
);
118 /*****************************************************************************
120 *****************************************************************************/
121 void msg_Disconnect( void )
127 /*****************************************************************************
129 *****************************************************************************/
130 void msg_Info( void *_unused
, const char *psz_format
, ... )
132 if ( i_verbose
< VERB_INFO
)
136 va_start( args
, psz_format
);
140 char psz_fmt
[MAX_MSG
];
141 snprintf( psz_fmt
, MAX_MSG
, "info: %s\n", psz_format
);
142 vfprintf( stderr
, psz_fmt
, args
);
146 vsyslog( LOG_INFO
, psz_format
, args
);
152 /*****************************************************************************
154 *****************************************************************************/
155 void msg_Err( void *_unused
, const char *psz_format
, ... )
157 if ( i_verbose
< VERB_ERR
)
161 va_start( args
, psz_format
);
165 char psz_fmt
[MAX_MSG
];
166 snprintf( psz_fmt
, MAX_MSG
, "error: %s\n", psz_format
);
167 vfprintf( stderr
, psz_fmt
, args
);
171 vsyslog( LOG_ERR
, psz_format
, args
);
177 /*****************************************************************************
179 *****************************************************************************/
180 void msg_Warn( void *_unused
, const char *psz_format
, ... )
182 if ( i_verbose
< VERB_WARN
)
186 va_start( args
, psz_format
);
190 char psz_fmt
[MAX_MSG
];
191 snprintf( psz_fmt
, MAX_MSG
, "warning: %s\n", psz_format
);
192 vfprintf( stderr
, psz_fmt
, args
);
196 vsyslog( LOG_WARNING
, psz_format
, args
);
202 /*****************************************************************************
204 *****************************************************************************/
205 void msg_Dbg( void *_unused
, const char *psz_format
, ... )
207 if ( i_verbose
< VERB_DBG
)
211 va_start( args
, psz_format
);
215 char psz_fmt
[MAX_MSG
];
216 snprintf( psz_fmt
, MAX_MSG
, "debug: %s\n", psz_format
);
217 vfprintf( stderr
, psz_fmt
, args
);
221 vsyslog( LOG_DEBUG
, psz_format
, args
);
227 /*****************************************************************************
229 *****************************************************************************/
230 void msg_Raw( void *_unused
, const char *psz_format
, ... )
233 char psz_fmt
[MAX_MSG
];
234 va_start( args
, psz_format
);
236 snprintf( psz_fmt
, MAX_MSG
, "%s\n", psz_format
);
237 vfprintf( stderr
, psz_fmt
, args
);
241 /*****************************************************************************
243 *****************************************************************************/
244 inline bool streq(char *a
, char *b
) {
245 if (!a
&& b
) return false;
246 if (!b
&& a
) return false;
247 if (a
== b
) return true;
248 return strcmp(a
, b
) == 0 ? true : false;
251 /*****************************************************************************
253 *****************************************************************************/
254 inline char * xstrdup(char *str
) {
255 return str
? strdup(str
) : NULL
;
258 /*****************************************************************************
260 *****************************************************************************/
261 void dvb_string_init(dvb_string_t
*p_dvb_string
)
263 p_dvb_string
->p
= NULL
;
267 /*****************************************************************************
269 *****************************************************************************/
270 void dvb_string_clean(dvb_string_t
*p_dvb_string
)
272 free(p_dvb_string
->p
);
275 /*****************************************************************************
277 *****************************************************************************/
278 void dvb_string_copy(dvb_string_t
*p_dst
, const dvb_string_t
*p_src
)
280 p_dst
->p
= malloc(p_src
->i
);
281 memcpy(p_dst
->p
, p_src
->p
, p_src
->i
);
285 /*****************************************************************************
287 *****************************************************************************/
288 int dvb_string_cmp(const dvb_string_t
*p_1
, const dvb_string_t
*p_2
)
290 if (p_1
->i
!= p_2
->i
)
291 return p_1
->i
- p_2
->i
;
292 return memcmp(p_1
->p
, p_2
->p
, p_1
->i
);
295 /*****************************************************************************
297 *****************************************************************************/
298 mtime_t
mdate( void )
300 #if defined (HAVE_CLOCK_NANOSLEEP)
303 /* Try to use POSIX monotonic clock if available */
304 if( clock_gettime( CLOCK_MONOTONIC
, &ts
) == EINVAL
)
305 /* Run-time fallback to real-time clock (always available) */
306 (void)clock_gettime( CLOCK_REALTIME
, &ts
);
308 return ((mtime_t
)ts
.tv_sec
* (mtime_t
)1000000)
309 + (mtime_t
)(ts
.tv_nsec
/ 1000);
311 struct timeval tv_date
;
313 /* gettimeofday() could return an error, and should be tested. However, the
314 * only possible error, according to 'man', is EFAULT, which can not happen
315 * here, since tv is a local variable. */
316 gettimeofday( &tv_date
, NULL
);
317 return( (mtime_t
) tv_date
.tv_sec
* 1000000 + (mtime_t
) tv_date
.tv_usec
);
321 /*****************************************************************************
323 *****************************************************************************/
324 void msleep( mtime_t delay
)
327 ts
.tv_sec
= delay
/ 1000000;
328 ts
.tv_nsec
= (delay
% 1000000) * 1000;
330 #if defined( HAVE_CLOCK_NANOSLEEP )
332 while ( ( val
= clock_nanosleep( CLOCK_MONOTONIC
, 0, &ts
, &ts
) ) == EINTR
);
335 ts
.tv_sec
= delay
/ 1000000;
336 ts
.tv_nsec
= (delay
% 1000000) * 1000;
337 while ( clock_nanosleep( CLOCK_REALTIME
, 0, &ts
, &ts
) == EINTR
);
340 while ( nanosleep( &ts
, &ts
) && errno
== EINTR
);
344 /*****************************************************************************
346 *****************************************************************************/
347 void hexDump( uint8_t *p_data
, uint32_t i_len
)
354 p_outline
= malloc(70);
355 p_hrdata
= malloc(18);
357 for( i
= 0; i
< i_len
; i
+= 16 )
360 sprintf( p_outline
, "%03x: ", i
);
362 for( j
= 0; j
< 16; j
++ )
366 sprintf( &p_outline
[5 + (3 * j
)], "%02x ", p_data
[i
+ j
] );
368 if( p_data
[i
+ j
] >= 32 && p_data
[i
+ j
] <= 136 )
370 sprintf( &p_hrdata
[j
], "%c", p_data
[i
+ j
] );
374 sprintf( &p_hrdata
[j
], "." );
380 sprintf( &p_outline
[5 + (3 * j
)], " " );
381 sprintf( &p_hrdata
[j
], " " );
385 sprintf( &p_outline
[53], "%16s", p_hrdata
);
386 msg_Dbg( NULL
, "%s", p_outline
);
393 /*****************************************************************************
394 * ParseNodeService: parse a host:port string
395 *****************************************************************************/
396 struct addrinfo
*ParseNodeService( char *_psz_string
, char **ppsz_end
,
397 uint16_t i_default_port
)
399 int i_family
= AF_INET
;
400 char psz_port_buffer
[6];
401 char *psz_string
= strdup( _psz_string
);
402 char *psz_node
, *psz_port
= NULL
, *psz_end
;
403 struct addrinfo
*p_res
;
404 struct addrinfo hint
;
407 if ( psz_string
[0] == '[' )
410 psz_node
= psz_string
+ 1;
411 psz_end
= strchr( psz_node
, ']' );
412 if ( psz_end
== NULL
)
414 msg_Warn( NULL
, "invalid IPv6 address %s", _psz_string
);
422 psz_node
= psz_string
;
423 psz_end
= strpbrk( psz_string
, "@:,/" );
426 if ( psz_end
!= NULL
&& psz_end
[0] == ':' )
430 psz_end
= strpbrk( psz_port
, "@:,/" );
433 if ( psz_end
!= NULL
)
436 if ( ppsz_end
!= NULL
)
437 *ppsz_end
= _psz_string
+ (psz_end
- psz_string
);
439 else if ( ppsz_end
!= NULL
)
440 *ppsz_end
= _psz_string
+ strlen(_psz_string
);
442 if ( i_default_port
!= 0 && (psz_port
== NULL
|| !*psz_port
) )
444 sprintf( psz_port_buffer
, "%u", i_default_port
);
445 psz_port
= psz_port_buffer
;
448 if ( psz_node
[0] == '\0' )
454 memset( &hint
, 0, sizeof(hint
) );
455 hint
.ai_family
= i_family
;
456 hint
.ai_socktype
= SOCK_DGRAM
;
457 hint
.ai_protocol
= 0;
458 hint
.ai_flags
= AI_PASSIVE
| AI_NUMERICHOST
| AI_NUMERICSERV
| AI_ADDRCONFIG
;
459 if ( (i_ret
= getaddrinfo( psz_node
, psz_port
, NULL
, &p_res
)) != 0 )
461 msg_Warn( NULL
, "getaddrinfo(host=%s, port=%s) error: %s",
462 psz_node
, psz_port
? psz_port
: "", gai_strerror(i_ret
) );
471 /*****************************************************************************
472 * psi_pack_section: return psi section
473 * Note: Allocates the return value. The caller must free it.
474 *****************************************************************************/
475 uint8_t *psi_pack_section( uint8_t *p_section
, unsigned int *pi_size
) {
476 uint8_t *p_flat_section
;
477 uint16_t psi_length
= psi_get_length( p_section
) + PSI_HEADER_SIZE
;
480 p_flat_section
= malloc( psi_length
);
481 if ( !p_flat_section
)
484 *pi_size
= psi_length
;
485 memcpy( p_flat_section
, p_section
, psi_length
);
487 return p_flat_section
;
490 /*****************************************************************************
491 * psi_pack_sections: return psi sections as array
492 * Note: Allocates the return value. The caller must free it.
493 *****************************************************************************/
494 uint8_t *psi_pack_sections( uint8_t **pp_sections
, unsigned int *pi_size
) {
495 uint8_t i_last_section
;
496 uint8_t *p_flat_section
;
497 unsigned int i
, i_pos
= 0;
499 if ( !psi_table_validate( pp_sections
) )
502 i_last_section
= psi_table_get_lastsection( pp_sections
);
504 /* Calculate total size */
506 for ( i
= 0; i
<= i_last_section
; i
++ )
508 uint8_t *p_section
= psi_table_get_section( pp_sections
, i
);
509 *pi_size
+= psi_get_length( p_section
) + PSI_HEADER_SIZE
;
512 p_flat_section
= malloc( *pi_size
);
513 if ( !p_flat_section
)
516 for ( i
= 0; i
<= i_last_section
; i
++ )
518 uint8_t *p_section
= psi_table_get_section( pp_sections
, i
);
519 uint16_t psi_length
= psi_get_length( p_section
) + PSI_HEADER_SIZE
;
521 memcpy( p_flat_section
+ i_pos
, p_section
, psi_length
);
525 return p_flat_section
;
529 /*****************************************************************************
530 * psi_unpack_sections: return psi sections
531 * Note: Allocates psi_table, the result must be psi_table_free()'ed
532 *****************************************************************************/
533 uint8_t **psi_unpack_sections( uint8_t *p_flat_sections
, unsigned int i_size
) {
534 uint8_t **pp_sections
;
535 unsigned int i
, i_offset
= 0;
537 pp_sections
= psi_table_allocate();
540 msg_Err( NULL
, "%s: cannot allocate PSI table\n", __func__
);
544 psi_table_init( pp_sections
);
546 for ( i
= 0; i
< PSI_TABLE_MAX_SECTIONS
; i
++ ) {
547 uint8_t *p_section
= p_flat_sections
+ i_offset
;
548 uint16_t i_section_len
= psi_get_length( p_section
) + PSI_HEADER_SIZE
;
550 if ( !psi_validate( p_section
) )
552 msg_Err( NULL
, "%s: Invalid section %d\n", __func__
, i
);
553 psi_table_free( pp_sections
);
557 /* Must use allocated section not p_flat_section + offset directly! */
558 uint8_t *p_section_local
= psi_private_allocate();
559 if ( !p_section_local
)
561 msg_Err( NULL
, "%s: cannot allocate PSI private\n", __func__
);
562 psi_table_free( pp_sections
);
565 memcpy( p_section_local
, p_section
, i_section_len
);
567 /* We ignore the return value of psi_table_section(), because it is useless
568 in this case. We are building the table section by section and when we have
569 more than one section in a table, psi_table_section() returns false when section
571 psi_table_section( pp_sections
, p_section_local
);
573 i_offset
+= i_section_len
;
574 if ( i_offset
>= i_size
- 1 )