@ -556,6 +556,9 @@ static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
/* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
# define TS_GAP_FOR_JB_RESYNC 5000
/* used for first_iax_message and last_iax_message. If this bit is set it was TX, else RX */
# define MARK_IAX_SUBCLASS_TX 0x8000
static int iaxthreadcount = DEFAULT_THREAD_COUNT ;
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT ;
static int iaxdynamicthreadcount = 0 ;
@ -595,6 +598,10 @@ struct chan_iax2_pvt {
unsigned int lastvsent ;
/*! Next outgoing timestamp if everything is good */
unsigned int nextpred ;
/*! iax frame subclass that began iax2_pvt entry. 0x8000 bit is set on TX */
int first_iax_message ;
/*! Last iax frame subclass sent or received for a iax2_pvt. 0x8000 bit is set on TX */
int last_iax_message ;
/*! True if the last voice we transmitted was not silence/CNG */
unsigned int notsilenttx : 1 ;
/*! Ping time */
@ -5130,6 +5137,13 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
}
pvt - > lastvsent = fts ;
}
if ( f - > frametype = = AST_FRAME_IAX ) {
/* 0x8000 marks this message as TX:, this bit will be stripped later */
pvt - > last_iax_message = f - > subclass | MARK_IAX_SUBCLASS_TX ;
if ( ! pvt - > first_iax_message ) {
pvt - > first_iax_message = pvt - > last_iax_message ;
}
}
/* Allocate an iax_frame */
if ( now ) {
fr = & frb . fr2 ;
@ -5205,7 +5219,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
} else
ast_log ( LOG_WARNING , " Supposed to send packet encrypted, but no key? \n " ) ;
}
if ( now ) {
res = send_packet ( fr ) ;
} else
@ -5824,11 +5838,13 @@ static int manager_iax2_show_registry(struct mansession *s, const struct message
static char * handle_cli_iax2_show_channels ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
# define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s \n"
# define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d / %5.5d %5.5d / %5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s \n"
# define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s \n"
# define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d / %5.5d %5.5d / %5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s \n"
# define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d / %5.5d %5.5d / %5.5d [Native Bridged to ID=%5.5d]\n"
int x ;
int numchans = 0 ;
char first_message [ 10 ] = { 0 , } ;
char last_message [ 10 ] = { 0 , } ;
switch ( cmd ) {
case CLI_INIT :
@ -5843,13 +5859,12 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
if ( a - > argc ! = 3 )
return CLI_SHOWUSAGE ;
ast_cli ( a - > fd , FORMAT2 , " Channel " , " Peer " , " Username " , " ID (Lo/Rem) " , " Seq (Tx/Rx) " , " Lag " , " Jitter " , " JitBuf " , " Format " );
ast_cli ( a - > fd , FORMAT2 , " Channel " , " Peer " , " Username " , " ID (Lo/Rem) " , " Seq (Tx/Rx) " , " Lag " , " Jitter " , " JitBuf " , " Format " , " FirstMsg " , " LastMsg " );
for ( x = 0 ; x < ARRAY_LEN ( iaxs ) ; x + + ) {
ast_mutex_lock ( & iaxsl [ x ] ) ;
if ( iaxs [ x ] ) {
int lag , jitter , localdelay ;
jb_info jbinfo ;
if ( ast_test_flag ( iaxs [ x ] , IAX_USEJITTERBUF ) ) {
jb_getinfo ( iaxs [ x ] - > jb , & jbinfo ) ;
jitter = jbinfo . jitter ;
@ -5858,17 +5873,24 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
jitter = - 1 ;
localdelay = 0 ;
}
iax_frame_subclass2str ( iaxs [ x ] - > first_iax_message & ~ MARK_IAX_SUBCLASS_TX , first_message , sizeof ( first_message ) ) ;
iax_frame_subclass2str ( iaxs [ x ] - > last_iax_message & ~ MARK_IAX_SUBCLASS_TX , last_message , sizeof ( last_message ) ) ;
lag = iaxs [ x ] - > remote_rr . delay ;
ast_cli ( a - > fd , FORMAT ,
iaxs [ x ] - > owner ? iaxs [ x ] - > owner - > name : " (None) " ,
ast_inet_ntoa ( iaxs [ x ] - > addr . sin_addr ) ,
ast_inet_ntoa ( iaxs [ x ] - > addr . sin_addr ) ,
S_OR ( iaxs [ x ] - > username , " (None) " ) ,
iaxs [ x ] - > callno , iaxs [ x ] - > peercallno ,
iaxs [ x ] - > oseqno , iaxs [ x ] - > iseqno ,
lag ,
jitter ,
localdelay ,
ast_getformatname ( iaxs [ x ] - > voiceformat ) ) ;
ast_getformatname ( iaxs [ x ] - > voiceformat ) ,
( iaxs [ x ] - > first_iax_message & MARK_IAX_SUBCLASS_TX ) ? " Tx: " : " Rx: " ,
first_message ,
( iaxs [ x ] - > last_iax_message & MARK_IAX_SUBCLASS_TX ) ? " Tx: " : " Rx: " ,
last_message ) ;
numchans + + ;
}
ast_mutex_unlock ( & iaxsl [ x ] ) ;
@ -5884,14 +5906,18 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
{
int x ;
int numchans = 0 ;
# define ACN_FORMAT1 "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"
# define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"
char first_message [ 10 ] = { 0 , } ;
char last_message [ 10 ] = { 0 , } ;
# define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
# define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
for ( x = 0 ; x < ARRAY_LEN ( iaxs ) ; x + + ) {
ast_mutex_lock ( & iaxsl [ x ] ) ;
if ( iaxs [ x ] ) {
int localjitter , localdelay , locallost , locallosspct , localdropped , localooo ;
jb_info jbinfo ;
iax_frame_subclass2str ( iaxs [ x ] - > first_iax_message & ~ MARK_IAX_SUBCLASS_TX , first_message , sizeof ( first_message ) ) ;
iax_frame_subclass2str ( iaxs [ x ] - > last_iax_message & ~ MARK_IAX_SUBCLASS_TX , last_message , sizeof ( last_message ) ) ;
if ( ast_test_flag ( iaxs [ x ] , IAX_USEJITTERBUF ) ) {
jb_getinfo ( iaxs [ x ] - > jb , & jbinfo ) ;
localjitter = jbinfo . jitter ;
@ -5909,29 +5935,32 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
localooo = - 1 ;
}
if ( s )
astman_append ( s , limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2 ,
iaxs [ x ] - > owner ? iaxs [ x ] - > owner - > name : " (None) " ,
iaxs [ x ] - > pingtime ,
localjitter ,
localdelay ,
locallost ,
locallosspct ,
localdropped ,
localooo ,
iaxs [ x ] - > frames_received / 1000 ,
iaxs [ x ] - > remote_rr . jitter ,
iaxs [ x ] - > remote_rr . delay ,
iaxs [ x ] - > remote_rr . losscnt ,
iaxs [ x ] - > remote_rr . losspct ,
iaxs [ x ] - > remote_rr . dropped ,
iaxs [ x ] - > remote_rr . ooo ,
iaxs [ x ] - > remote_rr . packets / 1000 ) ;
iaxs [ x ] - > owner ? iaxs [ x ] - > owner - > name : " (None) " ,
iaxs [ x ] - > pingtime ,
localjitter ,
localdelay ,
locallost ,
locallosspct ,
localdropped ,
localooo ,
iaxs [ x ] - > frames_received / 1000 ,
iaxs [ x ] - > remote_rr . jitter ,
iaxs [ x ] - > remote_rr . delay ,
iaxs [ x ] - > remote_rr . losscnt ,
iaxs [ x ] - > remote_rr . losspct ,
iaxs [ x ] - > remote_rr . dropped ,
iaxs [ x ] - > remote_rr . ooo ,
iaxs [ x ] - > remote_rr . packets / 1000 ,
( iaxs [ x ] - > first_iax_message & MARK_IAX_SUBCLASS_TX ) ? " Tx: " : " Rx: " ,
first_message ,
( iaxs [ x ] - > last_iax_message & MARK_IAX_SUBCLASS_TX ) ? " Tx: " : " Rx: " ,
last_message ) ;
else
ast_cli ( fd , limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2 ,
iaxs [ x ] - > owner ? iaxs [ x ] - > owner - > name : " (None) " ,
iaxs [ x ] - > pingtime ,
localjitter ,
localjitter ,
localdelay ,
locallost ,
locallosspct ,
@ -5944,8 +5973,11 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
iaxs [ x ] - > remote_rr . losspct ,
iaxs [ x ] - > remote_rr . dropped ,
iaxs [ x ] - > remote_rr . ooo ,
iaxs [ x ] - > remote_rr . packets / 1000
) ;
iaxs [ x ] - > remote_rr . packets / 1000 ,
( iaxs [ x ] - > first_iax_message & MARK_IAX_SUBCLASS_TX ) ? " Tx: " : " Rx: " ,
first_message ,
( iaxs [ x ] - > last_iax_message & MARK_IAX_SUBCLASS_TX ) ? " Tx: " : " Rx: " ,
last_message ) ;
numchans + + ;
}
ast_mutex_unlock ( & iaxsl [ x ] ) ;
@ -5970,15 +6002,13 @@ static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, str
}
if ( a - > argc ! = 3 )
return CLI_SHOWUSAGE ;
ast_cli ( a - > fd , " -------- LOCAL --------------------- -------- REMOTE --------------------\n " ) ;
ast_cli ( a - > fd , " Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n " ) ;
ast_cli ( a - > fd , " -------- LOCAL --------------------- -------- REMOTE --------------------\n " ) ;
ast_cli ( a - > fd , " Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg \n " ) ;
numchans = ast_cli_netstats ( NULL , a - > fd , 1 ) ;
ast_cli ( a - > fd , " %d active IAX channel%s \n " , numchans , ( numchans ! = 1 ) ? " s " : " " ) ;
return CLI_SUCCESS ;
}
static char * handle_cli_iax2_set_debug ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
switch ( cmd ) {
@ -8848,7 +8878,10 @@ retryowner:
if ( iaxdebug )
ast_debug ( 1 , " For call=%d, set last=%d \n " , fr - > callno , fr - > ts ) ;
}
iaxs [ fr - > callno ] - > last_iax_message = f . subclass ;
if ( ! iaxs [ fr - > callno ] - > first_iax_message ) {
iaxs [ fr - > callno ] - > first_iax_message = f . subclass ;
}
switch ( f . subclass ) {
case IAX_COMMAND_ACK :
/* Do nothing */