@ -676,63 +676,31 @@ struct statechange {
* Lock interface list find sc , iterate through each queues queue_member list for member to
* update state inside queues
*/
static void * handle_statechange ( struct statechange * sc )
static int update_status ( const char * interface , const int status )
{
struct call_queue * q ;
struct member * cur ;
struct ao2_iterator mem_iter ;
struct member_interface * curint ;
struct ao2_iterator queue_iter ;
char * loc ;
char * technology ;
technology = ast_strdupa ( sc - > dev ) ;
loc = strchr ( technology , ' / ' ) ;
if ( loc ) {
* loc + + = ' \0 ' ;
} else {
return NULL ;
}
AST_LIST_LOCK ( & interfaces ) ;
AST_LIST_TRAVERSE ( & interfaces , curint , list ) {
char * interface ;
char * slash_pos ;
interface = ast_strdupa ( curint - > interface ) ;
if ( ( slash_pos = strchr ( interface , ' / ' ) ) )
if ( ( slash_pos = strchr ( slash_pos + 1 , ' / ' ) ) )
* slash_pos = ' \0 ' ;
if ( ! strcasecmp ( interface , sc - > dev ) )
break ;
}
AST_LIST_UNLOCK ( & interfaces ) ;
if ( ! curint ) {
ast_debug ( 3 , " Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue. \n " , technology , loc , sc - > state , devstate2str ( sc - > state ) ) ;
return NULL ;
}
struct ao2_iterator mem_iter , queue_iter ;
struct call_queue * q ;
ast_debug ( 1 , " Device '%s/%s' changed to state '%d' (%s) \n " , technology , loc , sc - > state , devstate2str ( sc - > state ) ) ;
queue_iter = ao2_iterator_init ( queues , 0 ) ;
while ( ( q = ao2_iterator_next ( & queue_iter ) ) ) {
ao2_lock ( q ) ;
mem_iter = ao2_iterator_init ( q - > members , 0 ) ;
while ( ( cur = ao2_iterator_next ( & mem_iter ) ) ) {
char * interface;
char * tmp_interface ;
char * slash_pos ;
interface = ast_strdupa ( cur - > state_interface ) ;
tmp_interface = ast_strdupa ( cur - > state_interface ) ;
if ( ( slash_pos = strchr ( interface , ' / ' ) ) )
if ( ( slash_pos = strchr ( slash_pos + 1 , ' / ' ) ) )
* slash_pos = ' \0 ' ;
if ( strcasecmp ( sc- > dev , interface) ) {
if ( strcasecmp ( interface , tmp_interface ) ) {
ao2_ref ( cur , - 1 ) ;
continue ;
}
if ( cur - > status ! = s c- > state ) {
cur - > status = s c- > state ;
if ( cur - > status ! = status ) {
cur - > status = status ;
if ( q - > maskmemberstatus ) {
ao2_ref ( cur , - 1 ) ;
continue ;
@ -757,6 +725,49 @@ static void *handle_statechange(struct statechange *sc)
ao2_unlock ( q ) ;
}
return 0 ;
}
/*! \brief set a member's status based on device state of that member's interface*/
static void * handle_statechange ( struct statechange * sc )
{
struct member_interface * curint ;
char * loc ;
char * technology ;
technology = ast_strdupa ( sc - > dev ) ;
loc = strchr ( technology , ' / ' ) ;
if ( loc ) {
* loc + + = ' \0 ' ;
} else {
return NULL ;
}
AST_LIST_LOCK ( & interfaces ) ;
AST_LIST_TRAVERSE ( & interfaces , curint , list ) {
char * interface ;
char * slash_pos ;
interface = ast_strdupa ( curint - > interface ) ;
if ( ( slash_pos = strchr ( interface , ' / ' ) ) )
if ( ( slash_pos = strchr ( slash_pos + 1 , ' / ' ) ) )
* slash_pos = ' \0 ' ;
if ( ! strcasecmp ( interface , sc - > dev ) )
break ;
}
AST_LIST_UNLOCK ( & interfaces ) ;
if ( ! curint ) {
if ( option_debug > 2 )
ast_log ( LOG_DEBUG , " Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue. \n " , technology , loc , sc - > state , devstate2str ( sc - > state ) ) ;
return NULL ;
}
if ( option_debug )
ast_log ( LOG_DEBUG , " Device '%s/%s' changed to state '%d' (%s) \n " , technology , loc , sc - > state , devstate2str ( sc - > state ) ) ;
update_status ( sc - > dev , sc - > state ) ;
return NULL ;
}
@ -1991,55 +2002,6 @@ static void hangupcalls(struct callattempt *outgoing, struct ast_channel *except
}
}
static int update_status ( struct call_queue * q , struct member * member , int status )
{
struct member * cur ;
struct ao2_iterator mem_iter ;
/* Since a reload could have taken place, we have to traverse the list to
be sure it ' s still valid */
ao2_lock ( q ) ;
mem_iter = ao2_iterator_init ( q - > members , 0 ) ;
while ( ( cur = ao2_iterator_next ( & mem_iter ) ) ) {
if ( member ! = cur ) {
ao2_ref ( cur , - 1 ) ;
continue ;
}
cur - > status = status ;
if ( ! q - > maskmemberstatus ) {
manager_event ( EVENT_FLAG_AGENT , " QueueMemberStatus " ,
" Queue: %s \r \n "
" Location: %s \r \n "
" MemberName: %s \r \n "
" Membership: %s \r \n "
" Penalty: %d \r \n "
" CallsTaken: %d \r \n "
" LastCall: %d \r \n "
" Status: %d \r \n "
" Paused: %d \r \n " ,
q - > name , cur - > interface , cur - > membername , cur - > dynamic ? " dynamic " : cur - > realtime ? " realtime " : " static " ,
cur - > penalty , cur - > calls , ( int ) cur - > lastcall , cur - > status , cur - > paused ) ;
}
ao2_ref ( cur , - 1 ) ;
}
ao2_unlock ( q ) ;
return 0 ;
}
static int update_dial_status ( struct call_queue * q , struct member * member , int status )
{
if ( status = = AST_CAUSE_BUSY )
status = AST_DEVICE_BUSY ;
else if ( status = = AST_CAUSE_UNREGISTERED )
status = AST_DEVICE_UNAVAILABLE ;
else if ( status = = AST_CAUSE_NOSUCHDRIVER )
status = AST_DEVICE_INVALID ;
else
status = AST_DEVICE_UNKNOWN ;
return update_status ( q , member , status ) ;
}
/*!
* \ brief traverse all defined queues which have calls waiting and contain this member
* \ retval 0 if no other queue has precedence ( higher weight )
@ -2196,7 +2158,8 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
if ( qe - > chan - > cdr )
ast_cdr_busy ( qe - > chan - > cdr ) ;
tmp - > stillgoing = 0 ;
update_dial_status ( qe - > parent , tmp - > member , status ) ;
update_status ( tmp - > member - > state_interface , ast_device_state ( tmp - > member - > state_interface ) ) ;
ao2_lock ( qe - > parent ) ;
qe - > parent - > rrpos + + ;
@ -2206,8 +2169,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
( * busies ) + + ;
return 0 ;
} else if ( status ! = tmp - > oldstatus )
update_dial_status ( qe - > parent , tmp - > member , status ) ;
}
tmp - > chan - > appl = " AppQueue " ;
tmp - > chan - > data = " (Outgoing Line) " ;
@ -2576,8 +2538,6 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
ast_verb ( 3 , " Now forwarding %s to '%s/%s' (thanks to %s) \n " , in - > name , tech , stuff , o - > chan - > name ) ;
/* Setup parameters */
o - > chan = ast_request ( tech , in - > nativeformats , stuff , & status ) ;
if ( status ! = o - > oldstatus )
update_dial_status ( qe - > parent , o - > member , status ) ;
if ( ! o - > chan ) {
ast_log ( LOG_NOTICE , " Unable to create local channel for call forward to '%s/%s' \n " , tech , stuff ) ;
o - > stillgoing = 0 ;
@ -3290,8 +3250,8 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
to = ( qe - > parent - > timeout ) ? qe - > parent - > timeout * 1000 : - 1 ;
orig = to ;
+ + qe - > pending ;
ring_one ( qe , outgoing , & numbusies ) ;
ao2_unlock ( qe - > parent ) ;
ring_one ( qe , outgoing , & numbusies ) ;
if ( use_weight )
ao2_unlock ( queues ) ;
lpeer = wait_for_answer ( qe , outgoing , & to , & digit , numbusies , ast_test_flag ( & ( bridge_config . features_caller ) , AST_FEATURE_DISCONNECT ) , forwardsallowed ) ;