@ -1208,6 +1208,7 @@ struct member {
int paused ; /*!< Are we paused (not accepting calls)? */
int paused ; /*!< Are we paused (not accepting calls)? */
int queuepos ; /*!< In what order (pertains to certain strategies) should this member be called? */
int queuepos ; /*!< In what order (pertains to certain strategies) should this member be called? */
time_t lastcall ; /*!< When last successful call was hungup */
time_t lastcall ; /*!< When last successful call was hungup */
unsigned int in_call : 1 ; /*!< True if member is still in call. (so lastcall is not actual) */
struct call_queue * lastqueue ; /*!< Last queue we received a call */
struct call_queue * lastqueue ; /*!< Last queue we received a call */
unsigned int dead : 1 ; /*!< Used to detect members deleted in realtime */
unsigned int dead : 1 ; /*!< Used to detect members deleted in realtime */
unsigned int delme : 1 ; /*!< Flag to delete entry on reload */
unsigned int delme : 1 ; /*!< Flag to delete entry on reload */
@ -1647,6 +1648,10 @@ static int get_member_status(struct call_queue *q, int max_penalty, int min_pena
if ( member - > paused & & ( conditions & QUEUE_EMPTY_PAUSED ) ) {
if ( member - > paused & & ( conditions & QUEUE_EMPTY_PAUSED ) ) {
ast_debug ( 4 , " %s is unavailable because he is paused' \n " , member - > membername ) ;
ast_debug ( 4 , " %s is unavailable because he is paused' \n " , member - > membername ) ;
break ;
break ;
} else if ( ( conditions & QUEUE_EMPTY_WRAPUP ) & & member - > in_call & & q - > wrapuptime ) {
ast_debug ( 4 , " %s is unavailable because still in call, so we can`t check "
" wrapuptime (%d) \n " , member - > membername , q - > wrapuptime ) ;
break ;
} else if ( ( conditions & QUEUE_EMPTY_WRAPUP ) & & member - > lastcall & & q - > wrapuptime & & ( time ( NULL ) - q - > wrapuptime < member - > lastcall ) ) {
} else if ( ( conditions & QUEUE_EMPTY_WRAPUP ) & & member - > lastcall & & q - > wrapuptime & & ( time ( NULL ) - q - > wrapuptime < member - > lastcall ) ) {
ast_debug ( 4 , " %s is unavailable because it has only been %d seconds since his last call (wrapup time is %d) \n " , member - > membername , ( int ) ( time ( NULL ) - member - > lastcall ) , q - > wrapuptime ) ;
ast_debug ( 4 , " %s is unavailable because it has only been %d seconds since his last call (wrapup time is %d) \n " , member - > membername , ( int ) ( time ( NULL ) - member - > lastcall ) , q - > wrapuptime ) ;
break ;
break ;
@ -1721,6 +1726,13 @@ static int update_status(struct call_queue *q, struct member *m, const int statu
< parameter name = " LastCall " >
< parameter name = " LastCall " >
< para > The time this member last took call , expressed in seconds since 00 : 00 , Jan 1 , 1970 UTC . < / para >
< para > The time this member last took call , expressed in seconds since 00 : 00 , Jan 1 , 1970 UTC . < / para >
< / parameter >
< / parameter >
< parameter name = " InCall " >
< para > Set to 1 if member is in call . Set to 0 after LastCall time is updated . < / para >
< enumlist >
< enum name = " 0 " / >
< enum name = " 1 " / >
< / enumlist >
< / parameter >
< parameter name = " Status " >
< parameter name = " Status " >
< para > The numeric device state status of the queue member . < / para >
< para > The numeric device state status of the queue member . < / para >
< enumlist >
< enumlist >
@ -1753,10 +1765,11 @@ static int update_status(struct call_queue *q, struct member *m, const int statu
" Penalty: %d \r \n "
" Penalty: %d \r \n "
" CallsTaken: %d \r \n "
" CallsTaken: %d \r \n "
" LastCall: %d \r \n "
" LastCall: %d \r \n "
" InCall: %d \r \n "
" Status: %d \r \n "
" Status: %d \r \n "
" Paused: %d \r \n " ,
" Paused: %d \r \n " ,
q - > name , m - > interface , m - > membername , m - > state_interface , m - > dynamic ? " dynamic " : m - > realtime ? " realtime " : " static " ,
q - > name , m - > interface , m - > membername , m - > state_interface , m - > dynamic ? " dynamic " : m - > realtime ? " realtime " : " static " ,
m - > penalty , m - > calls , ( int ) m - > lastcall , m - > status, m - > paused
m - > penalty , m - > calls , ( int ) m - > lastcall , m - > in_call, m - > status, m - > paused
) ;
) ;
return 0 ;
return 0 ;
@ -1793,6 +1806,9 @@ static int is_member_available(struct call_queue *q, struct member *mem)
}
}
/* Let wrapuptimes override device state availability */
/* Let wrapuptimes override device state availability */
if ( q - > wrapuptime & & mem - > in_call ) {
available = 0 ; /* member is still in call, cant check wrapuptime to lastcall time */
}
if ( mem - > lastcall & & q - > wrapuptime & & ( time ( NULL ) - q - > wrapuptime < mem - > lastcall ) ) {
if ( mem - > lastcall & & q - > wrapuptime & & ( time ( NULL ) - q - > wrapuptime < mem - > lastcall ) ) {
available = 0 ;
available = 0 ;
}
}
@ -2158,6 +2174,7 @@ static void clear_queue(struct call_queue *q)
while ( ( mem = ao2_iterator_next ( & mem_iter ) ) ) {
while ( ( mem = ao2_iterator_next ( & mem_iter ) ) ) {
mem - > calls = 0 ;
mem - > calls = 0 ;
mem - > lastcall = 0 ;
mem - > lastcall = 0 ;
mem - > in_call = 0 ;
ao2_ref ( mem , - 1 ) ;
ao2_ref ( mem , - 1 ) ;
}
}
ao2_iterator_destroy ( & mem_iter ) ;
ao2_iterator_destroy ( & mem_iter ) ;
@ -3624,6 +3641,12 @@ static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
return 0 ;
return 0 ;
}
}
if ( call - > member - > in_call & & call - > lastqueue - > wrapuptime ) {
ast_debug ( 1 , " %s is in call, so not available (wrapuptime %d) \n " ,
call - > interface , call - > lastqueue - > wrapuptime ) ;
return 0 ;
}
if ( ( call - > lastqueue & & call - > lastqueue - > wrapuptime & & ( time ( NULL ) - call - > lastcall < call - > lastqueue - > wrapuptime ) )
if ( ( call - > lastqueue & & call - > lastqueue - > wrapuptime & & ( time ( NULL ) - call - > lastcall < call - > lastqueue - > wrapuptime ) )
| | ( ! call - > lastqueue & & qe - > parent - > wrapuptime & & ( time ( NULL ) - call - > lastcall < qe - > parent - > wrapuptime ) ) ) {
| | ( ! call - > lastqueue & & qe - > parent - > wrapuptime & & ( time ( NULL ) - call - > lastcall < qe - > parent - > wrapuptime ) ) ) {
ast_debug ( 1 , " Wrapuptime not yet expired on queue %s for %s \n " ,
ast_debug ( 1 , " Wrapuptime not yet expired on queue %s for %s \n " ,
@ -4903,6 +4926,9 @@ static int update_queue(struct call_queue *q, struct member *member, int callcom
time ( & mem - > lastcall ) ;
time ( & mem - > lastcall ) ;
mem - > calls + + ;
mem - > calls + + ;
mem - > lastqueue = q ;
mem - > lastqueue = q ;
mem - > in_call = 0 ;
ast_debug ( 4 , " Marked member %s as NOT in_call. Lastcall time: %ld \n " ,
mem - > membername , ( long ) mem - > lastcall ) ;
ao2_ref ( mem , - 1 ) ;
ao2_ref ( mem , - 1 ) ;
}
}
ao2_unlock ( qtmp ) ;
ao2_unlock ( qtmp ) ;
@ -4914,6 +4940,9 @@ static int update_queue(struct call_queue *q, struct member *member, int callcom
time ( & member - > lastcall ) ;
time ( & member - > lastcall ) ;
member - > calls + + ;
member - > calls + + ;
member - > lastqueue = q ;
member - > lastqueue = q ;
member - > in_call = 0 ;
ast_debug ( 4 , " Marked member %s as NOT in_call. Lastcall time: %ld \n " ,
member - > membername , ( long ) member - > lastcall ) ;
ao2_unlock ( q ) ;
ao2_unlock ( q ) ;
}
}
ao2_lock ( q ) ;
ao2_lock ( q ) ;
@ -5273,6 +5302,9 @@ static int try_calling(struct queue_ent *qe, const struct ast_flags opts, char *
struct ao2_iterator memi ;
struct ao2_iterator memi ;
struct ast_datastore * datastore , * transfer_ds ;
struct ast_datastore * datastore , * transfer_ds ;
struct queue_end_bridge * queue_end_bridge = NULL ;
struct queue_end_bridge * queue_end_bridge = NULL ;
struct ao2_iterator queue_iter ; /* to iterate through all queues (for shared_lastcall)*/
struct member * mem ;
struct call_queue * queuetmp ;
ast_channel_lock ( qe - > chan ) ;
ast_channel_lock ( qe - > chan ) ;
datastore = ast_channel_datastore_find ( qe - > chan , & dialed_interface_info , NULL ) ;
datastore = ast_channel_datastore_find ( qe - > chan , & dialed_interface_info , NULL ) ;
@ -5905,6 +5937,28 @@ static int try_calling(struct queue_ent *qe, const struct ast_flags opts, char *
}
}
}
}
qe - > handled + + ;
qe - > handled + + ;
/** mark member as "in_call" in all queues */
if ( shared_lastcall ) {
queue_iter = ao2_iterator_init ( queues , 0 ) ;
while ( ( queuetmp = ao2_t_iterator_next ( & queue_iter , " Iterate through queues " ) ) ) {
ao2_lock ( queuetmp ) ;
if ( ( mem = ao2_find ( queuetmp - > members , member , OBJ_POINTER ) ) ) {
mem - > in_call = 1 ;
ast_debug ( 4 , " Marked member %s as in_call \n " , mem - > membername ) ;
ao2_ref ( mem , - 1 ) ;
}
ao2_unlock ( queuetmp ) ;
queue_t_unref ( queuetmp , " Done with iterator " ) ;
}
ao2_iterator_destroy ( & queue_iter ) ;
} else {
ao2_lock ( qe - > parent ) ;
member - > in_call = 1 ;
ast_debug ( 4 , " Marked member %s as in_call \n " , member - > membername ) ;
ao2_unlock ( qe - > parent ) ;
}
ast_queue_log ( queuename , ast_channel_uniqueid ( qe - > chan ) , member - > membername , " CONNECT " , " %ld|%s|%ld " , ( long ) ( time ( NULL ) - qe - > start ) , ast_channel_uniqueid ( peer ) ,
ast_queue_log ( queuename , ast_channel_uniqueid ( qe - > chan ) , member - > membername , " CONNECT " , " %ld|%s|%ld " , ( long ) ( time ( NULL ) - qe - > start ) , ast_channel_uniqueid ( peer ) ,
( long ) ( orig - to > 0 ? ( orig - to ) / 1000 : 0 ) ) ;
( long ) ( orig - to > 0 ? ( orig - to ) / 1000 : 0 ) ) ;
@ -8455,10 +8509,11 @@ static char *__queues_show(struct mansession *s, int fd, int argc, const char *
ast_str_append ( & out , 0 , " (ringinuse %s) " , mem - > ringinuse ? " enabled " : " disabled " ) ;
ast_str_append ( & out , 0 , " (ringinuse %s) " , mem - > ringinuse ? " enabled " : " disabled " ) ;
ast_str_append ( & out , 0 , " %s%s%s (%s)" ,
ast_str_append ( & out , 0 , " %s%s%s %s (%s)" ,
mem - > dynamic ? " (dynamic) " : " " ,
mem - > dynamic ? " (dynamic) " : " " ,
mem - > realtime ? " (realtime) " : " " ,
mem - > realtime ? " (realtime) " : " " ,
mem - > paused ? " (paused) " : " " ,
mem - > paused ? " (paused) " : " " ,
mem - > in_call ? " (in call) " : " " ,
ast_devstate2str ( mem - > status ) ) ;
ast_devstate2str ( mem - > status ) ) ;
if ( mem - > calls ) {
if ( mem - > calls ) {
ast_str_append ( & out , 0 , " has taken %d calls (last was %ld secs ago) " ,
ast_str_append ( & out , 0 , " has taken %d calls (last was %ld secs ago) " ,
@ -8817,12 +8872,14 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
" Penalty: %d \r \n "
" Penalty: %d \r \n "
" CallsTaken: %d \r \n "
" CallsTaken: %d \r \n "
" LastCall: %d \r \n "
" LastCall: %d \r \n "
" IsInCall: %d \r \n "
" Status: %d \r \n "
" Status: %d \r \n "
" Paused: %d \r \n "
" Paused: %d \r \n "
" %s "
" %s "
" \r \n " ,
" \r \n " ,
q - > name , mem - > membername , mem - > interface , mem - > state_interface , mem - > dynamic ? " dynamic " : " static " ,
q - > name , mem - > membername , mem - > interface , mem - > state_interface , mem - > dynamic ? " dynamic " : " static " ,
mem - > penalty , mem - > calls , ( int ) mem - > lastcall , mem - > status , mem - > paused , idText ) ;
mem - > penalty , mem - > calls , ( int ) mem - > lastcall , mem - > in_call , mem - > status ,
mem - > paused , idText ) ;
}
}
ao2_ref ( mem , - 1 ) ;
ao2_ref ( mem , - 1 ) ;
}
}