@ -4473,67 +4473,30 @@ static int indicate_redirecting(struct ast_channel *chan, const void *data, size
return res ? - 1 : 0 ;
}
int ast_indicate_data ( struct ast_channel * chan , int _condition ,
const void * data , size_t datalen )
static int indicate_data_internal ( struct ast_channel * chan , int _condition , const void * data , size_t datalen )
{
/* By using an enum, we'll get compiler warnings for values not handled
* in switch statements . */
enum ast_control_frame_type condition = _condition ;
struct ast_tone_zone_sound * ts = NULL ;
int res ;
/* this frame is used by framehooks. if it is set, we must free it at the end of this function */
struct ast_frame * awesome_frame = NULL ;
ast_channel_lock ( chan ) ;
/* Don't bother if the channel is about to go away, anyway. */
if ( ( ast_test_flag ( ast_channel_flags ( chan ) , AST_FLAG_ZOMBIE )
| | ( ast_check_hangup ( chan ) & & ! ast_channel_is_leaving_bridge ( chan ) ) )
& & condition ! = AST_CONTROL_MASQUERADE_NOTIFY ) {
res = - 1 ;
goto indicate_cleanup ;
}
if ( ! ast_framehook_list_is_empty ( ast_channel_framehooks ( chan ) ) ) {
/* Do framehooks now, do it, go, go now */
struct ast_frame frame = {
. frametype = AST_FRAME_CONTROL ,
. subclass . integer = condition ,
. data . ptr = ( void * ) data , /* this cast from const is only okay because we do the ast_frdup below */
. datalen = datalen
} ;
/* we have now committed to freeing this frame */
awesome_frame = ast_frdup ( & frame ) ;
/* who knows what we will get back! the anticipation is killing me. */
if ( ! ( awesome_frame = ast_framehook_list_write_event ( ast_channel_framehooks ( chan ) , awesome_frame ) )
| | awesome_frame - > frametype ! = AST_FRAME_CONTROL ) {
res = 0 ;
goto indicate_cleanup ;
}
condition = awesome_frame - > subclass . integer ;
data = awesome_frame - > data . ptr ;
datalen = awesome_frame - > datalen ;
}
switch ( condition ) {
case AST_CONTROL_CONNECTED_LINE :
if ( indicate_connected_line ( chan , data , datalen ) ) {
res = 0 ;
goto indicate_cleanup ;
return res ;
}
break ;
case AST_CONTROL_REDIRECTING :
if ( indicate_redirecting ( chan , data , datalen ) ) {
res = 0 ;
goto indicate_cleanup ;
return res ;
}
break ;
case AST_CONTROL_HOLD :
case AST_CONTROL_UNHOLD :
ast_channel_hold_state_set ( chan , condition) ;
ast_channel_hold_state_set ( chan , _condition ) ;
break ;
default :
break ;
@ -4541,7 +4504,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
if ( is_visible_indication ( condition ) ) {
/* A new visible indication is requested. */
ast_channel_visible_indication_set ( chan , condition) ;
ast_channel_visible_indication_set ( chan , _ condition) ;
} else if ( condition = = AST_CONTROL_UNHOLD | | _condition < 0 ) {
/* Visible indication is cleared/stopped. */
ast_channel_visible_indication_set ( chan , 0 ) ;
@ -4549,7 +4512,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
if ( ast_channel_tech ( chan ) - > indicate ) {
/* See if the channel driver can handle this condition. */
res = ast_channel_tech ( chan ) - > indicate ( chan , condition, data , datalen ) ;
res = ast_channel_tech ( chan ) - > indicate ( chan , _ condition, data , datalen ) ;
} else {
res = - 1 ;
}
@ -4557,7 +4520,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
if ( ! res ) {
/* The channel driver successfully handled this indication */
res = 0 ;
goto indicate_cleanup ;
return res ;
}
/* The channel driver does not support this indication, let's fake
@ -4570,7 +4533,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
/* Stop any tones that are playing */
ast_playtones_stop ( chan ) ;
res = 0 ;
goto indicate_cleanup ;
return res ;
}
/* Handle conditions that we have tones for. */
@ -4578,7 +4541,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
case _XXX_AST_CONTROL_T38 :
/* deprecated T.38 control frame */
res = - 1 ;
goto indicate_cleanup ;
return res ;
case AST_CONTROL_T38_PARAMETERS :
/* there is no way to provide 'default' behavior for these
* control frames , so we need to return failure , but there
@ -4587,7 +4550,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
* so just return right now . in addition , we want to return
* whatever value the channel driver returned , in case it
* has some meaning . */
goto indicate_cleanup ;
return res ;
case AST_CONTROL_RINGING :
ts = ast_get_indication_tone ( ast_channel_zone ( chan ) , " ring " ) ;
/* It is common practice for channel drivers to return -1 if trying
@ -4670,6 +4633,53 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
ast_log ( LOG_WARNING , " Unable to handle indication %u for '%s' \n " , condition , ast_channel_name ( chan ) ) ;
}
return res ;
}
int ast_indicate_data ( struct ast_channel * chan , int _condition , const void * data , size_t datalen )
{
int res ;
/* this frame is used by framehooks. if it is set, we must free it at the end of this function */
struct ast_frame * awesome_frame = NULL ;
ast_channel_lock ( chan ) ;
/* Don't bother if the channel is about to go away, anyway. */
if ( ( ast_test_flag ( ast_channel_flags ( chan ) , AST_FLAG_ZOMBIE )
| | ( ast_check_hangup ( chan ) & & ! ast_channel_is_leaving_bridge ( chan ) ) )
& & _condition ! = AST_CONTROL_MASQUERADE_NOTIFY ) {
res = - 1 ;
goto indicate_cleanup ;
}
if ( ! ast_framehook_list_is_empty ( ast_channel_framehooks ( chan ) ) ) {
/* Do framehooks now, do it, go, go now */
struct ast_frame frame = {
. frametype = AST_FRAME_CONTROL ,
. subclass . integer = _condition ,
. data . ptr = ( void * ) data , /* this cast from const is only okay because we do the ast_frdup below */
. datalen = datalen
} ;
/* we have now committed to freeing this frame */
awesome_frame = ast_frdup ( & frame ) ;
/* who knows what we will get back! the anticipation is killing me. */
awesome_frame = ast_framehook_list_write_event ( ast_channel_framehooks ( chan ) ,
awesome_frame ) ;
if ( ! awesome_frame
| | awesome_frame - > frametype ! = AST_FRAME_CONTROL ) {
res = 0 ;
goto indicate_cleanup ;
}
_condition = awesome_frame - > subclass . integer ;
data = awesome_frame - > data . ptr ;
datalen = awesome_frame - > datalen ;
}
res = indicate_data_internal ( chan , _condition , data , datalen ) ;
indicate_cleanup :
ast_channel_unlock ( chan ) ;
if ( awesome_frame ) {
@ -5012,10 +5022,15 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
res = ast_senddigit_end ( chan , fr - > subclass . integer , fr - > len ) ;
ast_channel_lock ( chan ) ;
CHECK_BLOCKING ( chan ) ;
} else if ( fr - > frametype = = AST_FRAME_CONTROL & & fr - > subclass . integer = = AST_CONTROL_UNHOLD ) {
/* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
res = ( ast_channel_tech ( chan ) - > indicate = = NULL ) ? 0 :
ast_channel_tech ( chan ) - > indicate ( chan , fr - > subclass . integer , fr - > data . ptr , fr - > datalen ) ;
} else if ( fr - > frametype = = AST_FRAME_CONTROL
& & fr - > subclass . integer = = AST_CONTROL_UNHOLD ) {
/*
* This is a side case where Echo is basically being called
* and the person put themselves on hold and took themselves
* off hold .
*/
indicate_data_internal ( chan , fr - > subclass . integer , fr - > data . ptr ,
fr - > datalen ) ;
}
res = 0 ; /* XXX explain, why 0 ? */
goto done ;
@ -5027,8 +5042,8 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
CHECK_BLOCKING ( chan ) ;
switch ( fr - > frametype ) {
case AST_FRAME_CONTROL :
res = ( ast_channel_tech ( chan ) - > indicate = = NULL ) ? 0 :
ast_channel_tech ( chan ) - > indicate ( chan , fr - > subclass . integer , fr - > data . ptr , fr - > datalen ) ;
indicate_data_internal ( chan , fr - > subclass . integer , fr - > data . ptr , fr - > datalen ) ;
res = 0 ;
break ;
case AST_FRAME_DTMF_BEGIN :
if ( ast_channel_audiohooks ( chan ) ) {