@ -58,7 +58,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
# include "asterisk/causes.h"
# include "asterisk/musiconhold.h"
# include "asterisk/app.h"
# include "asterisk/devicestate.h"
# include "asterisk/stringfields.h"
# include "asterisk/threadstorage.h"
@ -1915,13 +1914,127 @@ static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *c
return e ;
}
void ast_devstate_aggregate_init ( struct ast_devstate_aggregate * agg )
{
memset ( agg , 0 , sizeof ( * agg ) ) ;
agg - > all_unknown = 1 ;
agg - > all_unavail = 1 ;
agg - > all_busy = 1 ;
agg - > all_free = 1 ;
}
void ast_devstate_aggregate_add ( struct ast_devstate_aggregate * agg , enum ast_device_state state )
{
switch ( state ) {
case AST_DEVICE_NOT_INUSE :
agg - > all_unknown = 0 ;
agg - > all_unavail = 0 ;
agg - > all_busy = 0 ;
break ;
case AST_DEVICE_INUSE :
agg - > in_use = 1 ;
agg - > all_unavail = 0 ;
agg - > all_free = 0 ;
agg - > all_unknown = 0 ;
break ;
case AST_DEVICE_RINGING :
agg - > ring = 1 ;
agg - > all_unavail = 0 ;
agg - > all_free = 0 ;
agg - > all_unknown = 0 ;
break ;
case AST_DEVICE_RINGINUSE :
agg - > in_use = 1 ;
agg - > ring = 1 ;
agg - > all_unavail = 0 ;
agg - > all_free = 0 ;
agg - > all_unknown = 0 ;
break ;
case AST_DEVICE_ONHOLD :
agg - > all_unknown = 0 ;
agg - > all_unavail = 0 ;
agg - > all_free = 0 ;
agg - > on_hold = 1 ;
break ;
case AST_DEVICE_BUSY :
agg - > all_unknown = 0 ;
agg - > all_unavail = 0 ;
agg - > all_free = 0 ;
agg - > busy = 1 ;
agg - > in_use = 1 ;
break ;
case AST_DEVICE_UNAVAILABLE :
agg - > all_unknown = 0 ;
case AST_DEVICE_INVALID :
agg - > all_busy = 0 ;
agg - > all_free = 0 ;
break ;
case AST_DEVICE_UNKNOWN :
agg - > all_busy = 0 ;
agg - > all_free = 0 ;
break ;
case AST_DEVICE_TOTAL : /* not a device state, included for completeness. */
break ;
}
}
enum ast_extension_states ast_devstate_to_extenstate ( enum ast_device_state devstate )
{
switch ( devstate ) {
case AST_DEVICE_ONHOLD :
return AST_EXTENSION_ONHOLD ;
case AST_DEVICE_BUSY :
return AST_EXTENSION_BUSY ;
case AST_DEVICE_UNAVAILABLE :
case AST_DEVICE_UNKNOWN :
case AST_DEVICE_INVALID :
return AST_EXTENSION_UNAVAILABLE ;
case AST_DEVICE_RINGINUSE :
return ( AST_EXTENSION_INUSE | AST_EXTENSION_RINGING ) ;
case AST_DEVICE_RINGING :
return AST_EXTENSION_RINGING ;
case AST_DEVICE_INUSE :
return AST_EXTENSION_INUSE ;
case AST_DEVICE_NOT_INUSE :
return AST_EXTENSION_NOT_INUSE ;
case AST_DEVICE_TOTAL : /* not a device state, included for completeness */
break ;
}
return AST_EXTENSION_NOT_INUSE ;
}
enum ast_device_state ast_devstate_aggregate_result ( struct ast_devstate_aggregate * agg )
{
if ( agg - > all_free )
return AST_DEVICE_NOT_INUSE ;
if ( ( agg - > in_use | | agg - > on_hold ) & & agg - > ring )
return AST_DEVICE_RINGINUSE ;
if ( agg - > ring )
return AST_DEVICE_RINGING ;
if ( agg - > busy )
return AST_DEVICE_BUSY ;
if ( agg - > in_use )
return AST_DEVICE_INUSE ;
if ( agg - > on_hold )
return AST_DEVICE_ONHOLD ;
if ( agg - > all_busy )
return AST_DEVICE_BUSY ;
if ( agg - > all_unknown )
return AST_DEVICE_UNKNOWN ;
if ( agg - > all_unavail )
return AST_DEVICE_UNAVAILABLE ;
return AST_DEVICE_NOT_INUSE ;
}
/*! \brief ast_extensions_state2: Check state of extension by using hints */
static int ast_extension_state2 ( struct ast_exten * e )
{
char hint [ AST_MAX_EXTENSION ] ;
char * cur , * rest ;
int allunavailable = 1 , allbusy = 1 , allfree = 1 ;
int busy = 0 , inuse = 0 , ring = 0 , onhold = 0 ;
struct ast_devstate_aggregate agg ;
ast_devstate_aggregate_init ( & agg ) ;
if ( ! e )
return - 1 ;
@ -1931,66 +2044,9 @@ static int ast_extension_state2(struct ast_exten *e)
rest = hint ; /* One or more devices separated with a & character */
while ( ( cur = strsep ( & rest , " & " ) ) ) {
int res = ast_device_state ( cur ) ;
switch ( res ) {
case AST_DEVICE_NOT_INUSE :
allunavailable = 0 ;
allbusy = 0 ;
break ;
case AST_DEVICE_INUSE :
inuse = 1 ;
allunavailable = 0 ;
allfree = 0 ;
break ;
case AST_DEVICE_RINGING :
ring = 1 ;
allunavailable = 0 ;
allfree = 0 ;
break ;
case AST_DEVICE_RINGINUSE :
inuse = 1 ;
ring = 1 ;
allunavailable = 0 ;
allfree = 0 ;
break ;
case AST_DEVICE_ONHOLD :
allunavailable = 0 ;
allfree = 0 ;
onhold = 1 ;
break ;
case AST_DEVICE_BUSY :
allunavailable = 0 ;
allfree = 0 ;
busy = 1 ;
inuse = 1 ;
break ;
case AST_DEVICE_UNAVAILABLE :
case AST_DEVICE_INVALID :
allbusy = 0 ;
allfree = 0 ;
break ;
default :
allunavailable = 0 ;
allbusy = 0 ;
allfree = 0 ;
}
ast_devstate_aggregate_add ( & agg , res ) ;
}
if ( allfree )
return AST_EXTENSION_NOT_INUSE ;
if ( ( inuse | | onhold ) & & ring )
return ( AST_EXTENSION_INUSE | AST_EXTENSION_RINGING ) ;
if ( allbusy )
return AST_EXTENSION_BUSY ;
if ( inuse )
return AST_EXTENSION_INUSE ;
if ( ring )
return AST_EXTENSION_RINGING ;
if ( onhold )
return AST_EXTENSION_ONHOLD ;
if ( allunavailable )
return AST_EXTENSION_UNAVAILABLE ;
return AST_EXTENSION_NOT_INUSE ;
return ast_devstate_to_extenstate ( ast_devstate_aggregate_result ( & agg ) ) ;
}
/*! \brief ast_extension_state2str: Return extension_state as string */
@ -3042,6 +3098,13 @@ void ast_unregister_switch(struct ast_switch *sw)
/*
* Help for CLI commands . . .
*/
# ifdef AST_DEVMODE
static char show_device2extenstate_help [ ] =
" Usage: core show device2extenstate \n "
" Lists device state to extension state combinations. \n " ;
# endif
static char show_applications_help [ ] =
" Usage: core show applications [{like|describing} <text>] \n "
" List applications which are currently available. \n "
@ -3756,8 +3819,26 @@ static int handle_set_global(int fd, int argc, char *argv[])
return RESULT_SUCCESS ;
}
# ifdef AST_DEVMODE
static int handle_show_device2extenstate ( int fd , int argc , char * argv [ ] )
{
struct ast_devstate_aggregate agg ;
int i , j , exten , combined ;
for ( i = 0 ; i < AST_DEVICE_TOTAL ; i + + ) {
for ( j = 0 ; j < AST_DEVICE_TOTAL ; j + + ) {
ast_devstate_aggregate_init ( & agg ) ;
ast_devstate_aggregate_add ( & agg , i ) ;
ast_devstate_aggregate_add ( & agg , j ) ;
combined = ast_devstate_aggregate_result ( & agg ) ;
exten = ast_devstate_to_extenstate ( combined ) ;
ast_cli ( fd , " \n Exten:%14s CombinedDevice:%12s Dev1:%12s Dev2:%12s " , ast_extension_state2str ( exten ) , devstate2str ( combined ) , devstate2str ( j ) , devstate2str ( i ) ) ;
}
}
ast_cli ( fd , " \n " ) ;
return RESULT_SUCCESS ;
}
# endif
/*
* CLI entries for upper commands . . .
@ -3828,6 +3909,12 @@ static struct ast_cli_entry pbx_cli[] = {
handle_show_globals , " Show global dialplan variables " ,
show_globals_help , NULL , & cli_show_globals_deprecated } ,
# ifdef AST_DEVMODE
{ { " core " , " show " , " device2extenstate " , NULL } ,
handle_show_device2extenstate , " Show expected exten state from multiple device states " ,
show_device2extenstate_help , NULL , NULL } ,
# endif
{ { " core " , " show " , " function " , NULL } ,
handle_show_function , " Describe a specific dialplan function " ,
show_function_help , complete_show_function , & cli_show_function_deprecated } ,