@ -237,6 +237,7 @@ static void set_agentbycallerid(const char *callerid, const char *agent);
static char * complete_agent_logoff_cmd ( const char * line , const char * word , int pos , int state ) ;
static char * complete_agent_logoff_cmd ( const char * line , const char * word , int pos , int state ) ;
static struct ast_channel * agent_get_base_channel ( struct ast_channel * chan ) ;
static struct ast_channel * agent_get_base_channel ( struct ast_channel * chan ) ;
static int agent_set_base_channel ( struct ast_channel * chan , struct ast_channel * base ) ;
static int agent_set_base_channel ( struct ast_channel * chan , struct ast_channel * base ) ;
static int agent_logoff ( const char * agent , int soft ) ;
/*! \brief Channel interface description for PBX integration */
/*! \brief Channel interface description for PBX integration */
static const struct ast_channel_tech agent_tech = {
static const struct ast_channel_tech agent_tech = {
@ -433,8 +434,12 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
struct ast_frame * f = NULL ;
struct ast_frame * f = NULL ;
static struct ast_frame answer_frame = { AST_FRAME_CONTROL , AST_CONTROL_ANSWER } ;
static struct ast_frame answer_frame = { AST_FRAME_CONTROL , AST_CONTROL_ANSWER } ;
const char * status ;
const char * status ;
int cur_time = time ( NULL ) ;
ast_mutex_lock ( & p - > lock ) ;
ast_mutex_lock ( & p - > lock ) ;
CHECK_FORMATS ( ast , p ) ;
CHECK_FORMATS ( ast , p ) ;
if ( ! p - > start ) {
p - > start = cur_time ;
}
if ( p - > chan ) {
if ( p - > chan ) {
ast_copy_flags ( p - > chan , ast , AST_FLAG_EXCEPTION ) ;
ast_copy_flags ( p - > chan , ast , AST_FLAG_EXCEPTION ) ;
p - > chan - > fdno = ( ast - > fdno = = AST_AGENT_FD ) ? AST_TIMING_FD : ast - > fdno ;
p - > chan - > fdno = ( ast - > fdno = = AST_AGENT_FD ) ? AST_TIMING_FD : ast - > fdno ;
@ -451,19 +456,16 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
if ( p - > chan )
if ( p - > chan )
ast_debug ( 1 , " Bridge on '%s' being cleared (2) \n " , p - > chan - > name ) ;
ast_debug ( 1 , " Bridge on '%s' being cleared (2) \n " , p - > chan - > name ) ;
if ( p - > owner - > _state ! = AST_STATE_UP ) {
if ( p - > owner - > _state ! = AST_STATE_UP ) {
int howlong = time ( NULL ) - p - > start ;
int howlong = cur_time - p - > start ;
if ( p - > autologoff & & howlong > p - > autologoff ) {
if ( p - > autologoff & & howlong > = p - > autologoff ) {
long logintime = time ( NULL ) - p - > loginstart ;
p - > loginstart = 0 ;
p - > loginstart = 0 ;
ast_log ( LOG_NOTICE , " Agent '%s' didn't answer/confirm within %d seconds (waited %d) \n " , p - > name , p - > autologoff , howlong ) ;
ast_log ( LOG_NOTICE , " Agent '%s' didn't answer/confirm within %d seconds (waited %d) \n " , p - > name , p - > autologoff , howlong ) ;
agent_logoff_maintenance ( p , p - > loginchan , logintime , ast - > uniqueid , " Autologoff " ) ;
agent_logoff_maintenance ( p , p - > loginchan , ( cur_time = p - > loginstart ) , ast - > uniqueid , " Autologoff " ) ;
if ( persistent_agents )
dump_agents ( ) ;
}
}
}
}
status = pbx_builtin_getvar_helper ( p - > chan , " CHANLOCALSTATUS " ) ;
status = pbx_builtin_getvar_helper ( p - > chan , " CHANLOCALSTATUS " ) ;
if ( autologoffunavail & & status & & ! strcasecmp ( status , " CHANUNAVAIL " ) ) {
if ( autologoffunavail & & status & & ! strcasecmp ( status , " CHANUNAVAIL " ) ) {
long logintime = time ( NULL ) - p - > loginstart ;
long logintime = cur_time - p - > loginstart ;
p - > loginstart = 0 ;
p - > loginstart = 0 ;
ast_log ( LOG_NOTICE , " Agent read: '%s' is not available now, auto logoff \n " , p - > name ) ;
ast_log ( LOG_NOTICE , " Agent read: '%s' is not available now, auto logoff \n " , p - > name ) ;
agent_logoff_maintenance ( p , p - > loginchan , logintime , ast - > uniqueid , " Chanunavail " ) ;
agent_logoff_maintenance ( p , p - > loginchan , logintime , ast - > uniqueid , " Chanunavail " ) ;
@ -479,8 +481,17 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
} else {
} else {
/* if acknowledgement is not required, and the channel is up, we may have missed
/* if acknowledgement is not required, and the channel is up, we may have missed
an AST_CONTROL_ANSWER ( if there was one ) , so mark the call acknowledged anyway */
an AST_CONTROL_ANSWER ( if there was one ) , so mark the call acknowledged anyway */
if ( ! p - > ackcall & & ! p - > acknowledged & & p - > chan & & ( p - > chan - > _state = = AST_STATE_UP ) )
if ( ! p - > ackcall & & ! p - > acknowledged & & p - > chan & & ( p - > chan - > _state = = AST_STATE_UP ) ) {
p - > acknowledged = 1 ;
p - > acknowledged = 1 ;
}
if ( ! p - > acknowledged ) {
int howlong = cur_time - p - > start ;
if ( p - > autologoff & & ( howlong > = p - > autologoff ) ) {
ast_log ( LOG_NOTICE , " Agent '%s' didn't answer/confirm within %d seconds (waited %d) \n " , p - > name , p - > autologoff , howlong ) ;
agent_logoff_maintenance ( p , p - > loginchan , ( cur_time - p - > loginstart ) , ast - > uniqueid , " Autologoff " ) ;
agent_logoff ( p - > agent , 0 ) ;
}
}
switch ( f - > frametype ) {
switch ( f - > frametype ) {
case AST_FRAME_CONTROL :
case AST_FRAME_CONTROL :
if ( f - > subclass = = AST_CONTROL_ANSWER ) {
if ( f - > subclass = = AST_CONTROL_ANSWER ) {