@ -259,16 +259,21 @@ static int adsi_announce_park(struct ast_channel *chan, int parkingnum)
return adsi_print ( chan , message , justify , 1 ) ;
return adsi_print ( chan , message , justify , 1 ) ;
}
}
int ast_park_call ( struct ast_channel * chan , struct ast_channel * peer , int timeout , int * extout )
/*--- ast_park_call: Park a call */
{
/* We put the user in the parking list, then wake up the parking thread to be sure it looks
/* We put the user in the parking list, then wake up the parking thread to be sure it looks
after these channels too */
after these channels too */
int ast_park_call ( struct ast_channel * chan , struct ast_channel * peer , int timeout , int * extout )
{
struct parkeduser * pu , * cur ;
struct parkeduser * pu , * cur ;
int i , x , parking_range ;
int i , x , parking_range ;
char exten [ AST_MAX_EXTENSION ] ;
char exten [ AST_MAX_EXTENSION ] ;
struct ast_context * con ;
struct ast_context * con ;
pu = malloc ( sizeof ( struct parkeduser ) ) ;
pu = malloc ( sizeof ( struct parkeduser ) ) ;
if ( pu ) {
if ( ! pu ) {
ast_log ( LOG_WARNING , " Out of memory \n " ) ;
return - 1 ;
}
memset ( pu , 0 , sizeof ( struct parkeduser ) ) ;
memset ( pu , 0 , sizeof ( struct parkeduser ) ) ;
ast_mutex_lock ( & parking_lock ) ;
ast_mutex_lock ( & parking_lock ) ;
parking_range = parking_stop - parking_start + 1 ;
parking_range = parking_stop - parking_start + 1 ;
@ -284,8 +289,14 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
break ;
break ;
}
}
if ( i < parking_range ) {
if ( ! ( i < parking_range ) ) {
if ( parkfindnext ) parking_offset = x - parking_start + 1 ;
ast_log ( LOG_WARNING , " No more parking spaces \n " ) ;
free ( pu ) ;
ast_mutex_unlock ( & parking_lock ) ;
return - 1 ;
}
if ( parkfindnext )
parking_offset = x - parking_start + 1 ;
chan - > appl = " Parked Call " ;
chan - > appl = " Parked Call " ;
chan - > data = NULL ;
chan - > data = NULL ;
@ -303,9 +314,9 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pu - > parkingtime = parkingtime ;
pu - > parkingtime = parkingtime ;
if ( extout )
if ( extout )
* extout = x ;
* extout = x ;
if ( peer ) {
if ( peer )
ast_copy_string ( pu - > peername , peer - > name , sizeof ( pu - > peername ) ) ;
ast_copy_string ( pu - > peername , peer - > name , sizeof ( pu - > peername ) ) ;
}
/* Remember what had been dialed, so that if the parking
/* Remember what had been dialed, so that if the parking
expires , we try to come back to the same place */
expires , we try to come back to the same place */
if ( ! ast_strlen_zero ( chan - > macrocontext ) )
if ( ! ast_strlen_zero ( chan - > macrocontext ) )
@ -329,7 +340,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
/* Wake up the (presumably select()ing) thread */
/* Wake up the (presumably select()ing) thread */
pthread_kill ( parking_thread , SIGURG ) ;
pthread_kill ( parking_thread , SIGURG ) ;
if ( option_verbose > 1 )
if ( option_verbose > 1 )
ast_verbose ( VERBOSE_PREFIX_2 " Parked %s on %d. Will timeout back to %s,%s, %d in %d seconds\n " , pu - > chan - > name , pu - > parkingnum , pu - > context , pu - > exten , pu - > priority , ( pu - > parkingtime / 1000 ) ) ;
ast_verbose ( VERBOSE_PREFIX_2 " Parked %s on %d. Will timeout back to extension [%s] %s, %d in %d seconds\n " , pu - > chan - > name , pu - > parkingnum , pu - > context , pu - > exten , pu - > priority , ( pu - > parkingtime / 1000 ) ) ;
manager_event ( EVENT_FLAG_CALL , " ParkedCall " ,
manager_event ( EVENT_FLAG_CALL , " ParkedCall " ,
" Exten: %d \r \n "
" Exten: %d \r \n "
@ -363,7 +374,8 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
snprintf ( exten , sizeof ( exten ) , " %d " , x ) ;
snprintf ( exten , sizeof ( exten ) , " %d " , x ) ;
ast_add_extension2 ( con , 1 , exten , 1 , NULL , NULL , parkedcall , strdup ( exten ) , FREE , registrar ) ;
ast_add_extension2 ( con , 1 , exten , 1 , NULL , NULL , parkedcall , strdup ( exten ) , FREE , registrar ) ;
}
}
if ( peer ) ast_say_digits ( peer , pu - > parkingnum , " " , peer - > language ) ;
if ( peer )
ast_say_digits ( peer , pu - > parkingnum , " " , peer - > language ) ;
if ( pu - > notquiteyet ) {
if ( pu - > notquiteyet ) {
/* Wake up parking thread if we're really done */
/* Wake up parking thread if we're really done */
ast_moh_start ( pu - > chan , NULL ) ;
ast_moh_start ( pu - > chan , NULL ) ;
@ -371,36 +383,29 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pthread_kill ( parking_thread , SIGURG ) ;
pthread_kill ( parking_thread , SIGURG ) ;
}
}
return 0 ;
return 0 ;
} else {
ast_log ( LOG_WARNING , " No more parking spaces \n " ) ;
free ( pu ) ;
ast_mutex_unlock ( & parking_lock ) ;
return - 1 ;
}
} else {
ast_log ( LOG_WARNING , " Out of memory \n " ) ;
return - 1 ;
}
return 0 ;
}
}
int ast_masq_park_call ( struct ast_channel * rchan , struct ast_channel * peer , int timeout , int * extout )
int ast_masq_park_call ( struct ast_channel * rchan , struct ast_channel * peer , int timeout , int * extout )
{
{
struct ast_channel * chan ;
struct ast_channel * chan ;
struct ast_frame * f ;
struct ast_frame * f ;
/* Make a new, fake channel that we'll use to masquerade in the real one */
/* Make a new, fake channel that we'll use to masquerade in the real one */
chan = ast_channel_alloc ( 0 ) ;
chan = ast_channel_alloc ( 0 ) ;
if ( chan ) {
if ( chan ) {
/* Let us keep track of the channel name */
/* Let us keep track of the channel name */
snprintf ( chan - > name , sizeof ( chan - > name ) , " Parked/%s " , rchan - > name ) ;
snprintf ( chan - > name , sizeof ( chan - > name ) , " Parked/%s " , rchan - > name ) ;
/* Make formats okay */
/* Make formats okay */
chan - > readformat = rchan - > readformat ;
chan - > readformat = rchan - > readformat ;
chan - > writeformat = rchan - > writeformat ;
chan - > writeformat = rchan - > writeformat ;
ast_channel_masquerade ( chan , rchan ) ;
ast_channel_masquerade ( chan , rchan ) ;
/* Setup the extensions and such */
/* Setup the extensions and such */
ast_copy_string ( chan - > context , rchan - > context , sizeof ( chan - > context ) ) ;
ast_copy_string ( chan - > context , rchan - > context , sizeof ( chan - > context ) ) ;
ast_copy_string ( chan - > exten , rchan - > exten , sizeof ( chan - > exten ) ) ;
ast_copy_string ( chan - > exten , rchan - > exten , sizeof ( chan - > exten ) ) ;
chan - > priority = rchan - > priority ;
chan - > priority = rchan - > priority ;
/* Make the masq execute */
/* Make the masq execute */
f = ast_read ( chan ) ;
f = ast_read ( chan ) ;
if ( f )
if ( f )
@ -1106,7 +1111,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
int hasfeatures = 0 ;
int hasfeatures = 0 ;
int hadfeatures = 0 ;
int hadfeatures = 0 ;
struct ast_option_header * aoh ;
struct ast_option_header * aoh ;
struct timeval start ;
struct timeval start = { 0 , 0 } ;
struct ast_bridge_config backup_config ;
struct ast_bridge_config backup_config ;
int allowdisconnect_in , allowdisconnect_out , allowredirect_in , allowredirect_out ;
int allowdisconnect_in , allowdisconnect_out , allowredirect_in , allowredirect_out ;
char * monitor_exec ;
char * monitor_exec ;
@ -1142,6 +1147,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
return - 1 ;
return - 1 ;
peer - > appl = " Bridged Call " ;
peer - > appl = " Bridged Call " ;
peer - > data = chan - > name ;
peer - > data = chan - > name ;
/* copy the userfield from the B-leg to A-leg if applicable */
/* copy the userfield from the B-leg to A-leg if applicable */
if ( chan - > cdr & & peer - > cdr & & ! ast_strlen_zero ( peer - > cdr - > userfield ) ) {
if ( chan - > cdr & & peer - > cdr & & ! ast_strlen_zero ( peer - > cdr - > userfield ) ) {
char tmp [ 256 ] ;
char tmp [ 256 ] ;
@ -1253,6 +1259,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
char * featurecode ;
char * featurecode ;
int sense ;
int sense ;
struct ast_channel * other ;
struct ast_channel * other ;
hadfeatures = hasfeatures ;
hadfeatures = hasfeatures ;
/* This cannot overrun because the longest feature is one shorter than our buffer */
/* This cannot overrun because the longest feature is one shorter than our buffer */
if ( who = = chan ) {
if ( who = = chan ) {
@ -1688,6 +1695,7 @@ static char showparked_help[] =
static struct ast_cli_entry showparked =
static struct ast_cli_entry showparked =
{ { " show " , " parkedcalls " , NULL } , handle_parkedcalls , " Lists parked calls " , showparked_help } ;
{ { " show " , " parkedcalls " , NULL } , handle_parkedcalls , " Lists parked calls " , showparked_help } ;
/* Dump lot status */
/* Dump lot status */
static int manager_parking_status ( struct mansession * s , struct message * m )
static int manager_parking_status ( struct mansession * s , struct message * m )
{
{
@ -1734,6 +1742,41 @@ static int manager_parking_status( struct mansession *s, struct message *m )
}
}
int ast_pickup_call ( struct ast_channel * chan )
{
struct ast_channel * cur = NULL ;
int res = - 1 ;
while ( ( cur = ast_channel_walk_locked ( cur ) ) ! = NULL ) {
if ( ! cur - > pbx & &
( cur ! = chan ) & &
( chan - > pickupgroup & cur - > callgroup ) & &
( ( cur - > _state = = AST_STATE_RINGING ) | |
( cur - > _state = = AST_STATE_RING ) ) ) {
break ;
}
ast_mutex_unlock ( & cur - > lock ) ;
}
if ( cur ) {
if ( option_debug )
ast_log ( LOG_DEBUG , " Call pickup on chan '%s' by '%s' \n " , cur - > name , chan - > name ) ;
res = ast_answer ( chan ) ;
if ( res )
ast_log ( LOG_WARNING , " Unable to answer '%s' \n " , chan - > name ) ;
res = ast_queue_control ( chan , AST_CONTROL_ANSWER ) ;
if ( res )
ast_log ( LOG_WARNING , " Unable to queue answer on '%s' \n " , chan - > name ) ;
res = ast_channel_masquerade ( cur , chan ) ;
if ( res )
ast_log ( LOG_WARNING , " Unable to masquerade '%s' into '%s' \n " , chan - > name , cur - > name ) ; /* Done */
ast_mutex_unlock ( & cur - > lock ) ;
} else {
if ( option_debug )
ast_log ( LOG_DEBUG , " No call pickup possible... \n " ) ;
}
return res ;
}
static int load_config ( void )
static int load_config ( void )
{
{
int start = 0 , end = 0 ;
int start = 0 , end = 0 ;
@ -1839,39 +1882,6 @@ int load_module(void)
return res ;
return res ;
}
}
int ast_pickup_call ( struct ast_channel * chan )
{
struct ast_channel * cur = NULL ;
int res = - 1 ;
while ( ( cur = ast_channel_walk_locked ( cur ) ) ! = NULL ) {
if ( ! cur - > pbx & &
( cur ! = chan ) & &
( chan - > pickupgroup & cur - > callgroup ) & &
( ( cur - > _state = = AST_STATE_RINGING ) | |
( cur - > _state = = AST_STATE_RING ) ) ) {
break ;
}
ast_mutex_unlock ( & cur - > lock ) ;
}
if ( cur ) {
if ( option_debug )
ast_log ( LOG_DEBUG , " Call pickup on chan '%s' by '%s' \n " , cur - > name , chan - > name ) ;
res = ast_answer ( chan ) ;
if ( res )
ast_log ( LOG_WARNING , " Unable to answer '%s' \n " , chan - > name ) ;
res = ast_queue_control ( chan , AST_CONTROL_ANSWER ) ;
if ( res )
ast_log ( LOG_WARNING , " Unable to queue answer on '%s' \n " , chan - > name ) ;
res = ast_channel_masquerade ( cur , chan ) ;
if ( res )
ast_log ( LOG_WARNING , " Unable to masquerade '%s' into '%s' \n " , chan - > name , cur - > name ) ; /* Done */
ast_mutex_unlock ( & cur - > lock ) ;
} else {
if ( option_debug )
ast_log ( LOG_DEBUG , " No call pickup possible... \n " ) ;
}
return res ;
}
int unload_module ( void )
int unload_module ( void )
{
{
@ -1886,7 +1896,7 @@ int unload_module(void)
char * description ( void )
char * description ( void )
{
{
return " Call Parking Resource" ;
return " Call Features Resource" ;
}
}
int usecount ( void )
int usecount ( void )