@ -46,7 +46,7 @@ static const char *tdesc = "Directed Call Pickup Application";
static const char * app = " Pickup " ;
static const char * synopsis = " Directed Call Pickup " ;
static const char * descrip =
" Pickup(extension[@context] ): This application can pickup any ringing channel\n "
" Pickup(extension[@context] [&extension2@context...] ): This application can pickup any ringing channel\n "
" that is calling the specified extension. If no context is specified, the current \n "
" context will be used. \n " ;
@ -59,7 +59,7 @@ static int pickup_exec(struct ast_channel *chan, void *data)
int res = 0 ;
struct localuser * u = NULL ;
struct ast_channel * origin = NULL , * target = NULL ;
char * tmp = NULL , * exten = NULL , * context = NULL ;
char * tmp = NULL , * exten = NULL , * context = NULL , * rest = data ;
char workspace [ 256 ] = " " ;
if ( ast_strlen_zero ( data ) ) {
@ -69,64 +69,65 @@ static int pickup_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD ( u ) ;
/* Get the extension and context if present */
exten = data ;
context = strchr ( data , ' @ ' ) ;
if ( context ) {
* context = ' \0 ' ;
context + + ;
}
while ( ! target & & ( exten = rest ) ) {
res = 0 ;
rest = strchr ( exten , ' & ' ) ;
if ( rest )
* rest + + = 0 ;
/* Get the extension and context if present */
context = strchr ( exten , ' @ ' ) ;
if ( context )
* context + + = ' \0 ' ;
/* Find a channel to pickup */
origin = ast_get_channel_by_exten_locked ( exten , context ) ;
if ( origin ) {
ast_cdr_getvar ( origin - > cdr , " dstchannel " , & tmp , workspace ,
sizeof ( workspace ) , 0 ) ;
if ( tmp ) {
/* We have a possible channel... now we need to find it! */
target = ast_get_channel_by_name_locked ( tmp ) ;
} else {
ast_log ( LOG_NOTICE , " No target channel found for %s. \n " , exten ) ;
res = - 1 ;
}
ast_mutex_unlock ( & origin - > lock ) ;
/* Find a channel to pickup */
origin = ast_get_channel_by_exten_locked ( exten , context ) ;
if ( origin & & origin - > cdr ) {
ast_cdr_getvar ( origin - > cdr , " dstchannel " , & tmp , workspace ,
sizeof ( workspace ) , 0 ) ;
if ( tmp ) {
/* We have a possible channel... now we need to find it! */
target = ast_get_channel_by_name_locked ( tmp ) ;
} else {
ast_log ( LOG_DEBUG , " No target channel found. \n " ) ;
res = - 1 ;
}
ast_mutex_unlock ( & origin - > lock ) ;
} else {
if ( origin )
ast_mutex_unlock ( & origin - > lock ) ;
ast_log ( LOG_DEBUG , " No originating channel found. \n " ) ;
}
if ( res )
goto out ;
if ( target & & ( ! target - > pbx ) & & ( ( target - > _state = = AST_STATE_RINGING ) | | ( target - > _state = = AST_STATE_RING ) ) ) {
ast_log ( LOG_DEBUG , " Call pickup on chan '%s' by '%s' \n " , target - > name ,
chan - > name ) ;
res = ast_answer ( chan ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Unable to answer '%s' \n " , chan - > name ) ;
res = - 1 ;
goto out ;
}
res = ast_queue_control ( chan , AST_CONTROL_ANSWER ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Unable to queue answer on '%s' \n " ,
chan - > name ) ;
res = - 1 ;
goto out ;
ast_log ( LOG_DEBUG , " No originating channel found. \n " ) ;
}
res = ast_channel_masquerade ( target , chan ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Unable to masquerade '%s' into '%s' \n " , chan - > name , target - > name ) ;
if ( res )
continue ;
if ( target & & ( ! target - > pbx ) & & ( ( target - > _state = = AST_STATE_RINGING ) | | ( target - > _state = = AST_STATE_RING ) ) ) {
ast_log ( LOG_DEBUG , " Call pickup on chan '%s' by '%s' \n " , target - > name ,
chan - > name ) ;
res = ast_answer ( chan ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Unable to answer '%s' \n " , chan - > name ) ;
res = - 1 ;
break ;
}
res = ast_queue_control ( chan , AST_CONTROL_ANSWER ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Unable to queue answer on '%s' \n " ,
chan - > name ) ;
res = - 1 ;
break ;
}
res = ast_channel_masquerade ( target , chan ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Unable to masquerade '%s' into '%s' \n " , chan - > name , target - > name ) ;
res = - 1 ;
break ;
}
} else {
ast_log ( LOG_NOTICE , " No call pickup possible for %s... \n " , exten ) ;
res = - 1 ;
goto out ;
}
} else {
ast_log ( LOG_DEBUG , " No call pickup possible... \n " ) ;
res = - 1 ;
}
/* Done */
out :
if ( target )
ast_mutex_unlock ( & target - > lock ) ;