@ -212,9 +212,6 @@ static char moh[80] = "default";
static const char pa_family [ ] = " Agents " ; /*!< Persistent Agents astdb family */
# define PA_MAX_LEN 2048 /*!< The maximum length of each persistent member agent database entry */
static int persistent_agents = 0 ; /*!< queues.conf [general] option */
static void dump_agents ( void ) ;
# define DEFAULT_ACCEPTDTMF '#'
# define DEFAULT_ENDDTMF '*'
@ -275,7 +272,6 @@ struct agent_pvt {
ast_cond_t app_complete_cond ;
volatile int app_sleep_cond ; /**< Sleep condition for the login app */
struct ast_channel * owner ; /**< Agent */
char loginchan [ 80 ] ; /**< channel they logged in from */
char logincallerid [ 80 ] ; /**< Caller ID they had when they logged in */
struct ast_channel * chan ; /**< Channel we use */
unsigned int flags ; /**< Flags show if settings were applied with channel vars */
@ -319,7 +315,6 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (l
/*--- Forward declarations */
static struct ast_channel * agent_request ( const char * type , int format , void * data , int * cause ) ;
static int agent_devicestate ( void * data ) ;
static void agent_logoff_maintenance ( struct agent_pvt * p , char * loginchan , long logintime , const char * uniqueid , char * logcommand ) ;
static int agent_digit_begin ( struct ast_channel * ast , char digit ) ;
static int agent_digit_end ( struct ast_channel * ast , char digit , unsigned int duration ) ;
static int agent_call ( struct ast_channel * ast , char * dest , int timeout ) ;
@ -332,7 +327,6 @@ static int agent_sendtext(struct ast_channel *ast, const char *text);
static int agent_indicate ( struct ast_channel * ast , int condition , const void * data , size_t datalen ) ;
static int agent_fixup ( struct ast_channel * oldchan , struct ast_channel * newchan ) ;
static struct ast_channel * agent_bridgedchannel ( struct ast_channel * chan , struct ast_channel * bridge ) ;
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 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 ) ;
@ -539,7 +533,6 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
struct agent_pvt * p = ast - > tech_pvt ;
struct ast_frame * f = NULL ;
static struct ast_frame answer_frame = { AST_FRAME_CONTROL , AST_CONTROL_ANSWER } ;
const char * status ;
int cur_time = time ( NULL ) ;
ast_mutex_lock ( & p - > lock ) ;
CHECK_FORMATS ( ast , p ) ;
@ -553,33 +546,9 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
} else
f = & ast_null_frame ;
if ( ! f ) {
/* If there's a channel, hang it up (if it's on a callback) make it NULL */
/* If there's a channel, make it NULL */
if ( p - > chan ) {
p - > chan - > _bridge = NULL ;
/* Note that we don't hangup if it's not a callback because Asterisk will do it
for us when the PBX instance that called login finishes */
if ( ! ast_strlen_zero ( p - > loginchan ) ) {
if ( p - > chan )
ast_debug ( 1 , " Bridge on '%s' being cleared (2) \n " , p - > chan - > name ) ;
if ( p - > owner - > _state ! = AST_STATE_UP ) {
int howlong = cur_time - p - > start ;
if ( p - > autologoff & & howlong > = p - > autologoff ) {
p - > loginstart = 0 ;
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 " ) ;
}
}
status = pbx_builtin_getvar_helper ( p - > chan , " CHANLOCALSTATUS " ) ;
if ( autologoffunavail & & status & & ! strcasecmp ( status , " CHANUNAVAIL " ) ) {
long logintime = cur_time - p - > loginstart ;
p - > loginstart = 0 ;
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 " ) ;
}
ast_hangup ( p - > chan ) ;
if ( p - > wrapuptime & & p - > acknowledged )
p - > lastdisc = ast_tvadd ( ast_tvnow ( ) , ast_samp2tv ( p - > wrapuptime , 1000 ) ) ;
}
p - > chan = NULL ;
ast_devstate_changed ( AST_DEVICE_UNAVAILABLE , " Agent/%s " , p - > agent ) ;
p - > acknowledged = 0 ;
@ -595,7 +564,6 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
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 ) ;
}
}
@ -784,16 +752,6 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
if ( newstate )
ast_setstate ( ast , newstate ) ;
return res ;
} else if ( ! ast_strlen_zero ( p - > loginchan ) ) {
time ( & p - > start ) ;
/* Call on this agent */
ast_verb ( 3 , " outgoing agentcall, to agent '%s', on '%s' \n " , p - > agent , p - > chan - > name ) ;
ast_channel_set_connected_line ( p - > chan , & ast - > connected ) ;
ast_channel_inherit_variables ( ast , p - > chan ) ;
res = ast_call ( p - > chan , p - > loginchan , 0 ) ;
CLEANUP ( ast , p ) ;
ast_mutex_unlock ( & p - > lock ) ;
return res ;
}
ast_verb ( 3 , " agent_call, call to agent '%s' call on '%s' \n " , p - > agent , p - > chan - > name ) ;
ast_debug ( 3 , " Playing beep, lang '%s' \n " , p - > chan - > language ) ;
@ -822,9 +780,9 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
}
if ( ! res ) {
/* Call is immediately up, or might need ack */
if ( p - > ackcall > 1 )
if ( p - > ackcall ) {
newstate = AST_STATE_RINGING ;
else {
} else {
newstate = AST_STATE_UP ;
if ( recordagentcalls )
agent_start_monitoring ( ast , 0 ) ;
@ -839,19 +797,6 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
return res ;
}
/*! \brief store/clear the global variable that stores agentid based on the callerid */
static void set_agentbycallerid ( const char * callerid , const char * agent )
{
char buf [ AST_MAX_BUF ] ;
/* if there is no Caller ID, nothing to do */
if ( ast_strlen_zero ( callerid ) )
return ;
snprintf ( buf , sizeof ( buf ) , " %s_%s " , GETAGENTBYCALLERID , callerid ) ;
pbx_builtin_setvar_helper ( NULL , buf , agent ) ;
}
/*! \brief return the channel or base channel if one exists. This function assumes the channel it is called on is already locked */
struct ast_channel * agent_get_base_channel ( struct ast_channel * chan )
{
@ -890,7 +835,7 @@ static int agent_hangup(struct ast_channel *ast)
{
struct agent_pvt * p = ast - > tech_pvt ;
int howlong = 0 ;
const char * status ;
ast_mutex_lock ( & p - > lock ) ;
p - > owner = NULL ;
ast - > tech_pvt = NULL ;
@ -915,37 +860,7 @@ static int agent_hangup(struct ast_channel *ast)
if ( p - > chan ) {
p - > chan - > _bridge = NULL ;
/* If they're dead, go ahead and hang up on the agent now */
if ( ! ast_strlen_zero ( p - > loginchan ) ) {
/* Store last disconnect time */
if ( p - > wrapuptime )
p - > lastdisc = ast_tvadd ( ast_tvnow ( ) , ast_samp2tv ( p - > wrapuptime , 1000 ) ) ;
else
p - > lastdisc = ast_tv ( 0 , 0 ) ;
if ( p - > chan ) {
status = pbx_builtin_getvar_helper ( p - > chan , " CHANLOCALSTATUS " ) ;
if ( autologoffunavail & & status & & ! strcasecmp ( status , " CHANUNAVAIL " ) ) {
long logintime = time ( NULL ) - p - > loginstart ;
p - > loginstart = 0 ;
ast_log ( LOG_NOTICE , " Agent hangup: '%s' is not available now, auto logoff \n " , p - > name ) ;
agent_logoff_maintenance ( p , p - > loginchan , logintime , ast - > uniqueid , " Chanunavail " ) ;
}
/* Recognize the hangup and pass it along immediately */
ast_hangup ( p - > chan ) ;
p - > chan = NULL ;
ast_devstate_changed ( AST_DEVICE_UNAVAILABLE , " Agent/%s " , p - > agent ) ;
}
ast_debug ( 1 , " Hungup, howlong is %d, autologoff is %d \n " , howlong , p - > autologoff ) ;
if ( ( p - > deferlogoff ) | | ( howlong & & p - > autologoff & & ( howlong > p - > autologoff ) ) ) {
long logintime = time ( NULL ) - p - > loginstart ;
p - > loginstart = 0 ;
if ( ! p - > deferlogoff )
ast_log ( LOG_NOTICE , " Agent '%s' didn't answer/confirm within %d seconds (waited %d) \n " , p - > name , p - > autologoff , howlong ) ;
p - > deferlogoff = 0 ;
agent_logoff_maintenance ( p , p - > loginchan , logintime , ast - > uniqueid , " Autologoff " ) ;
if ( persistent_agents )
dump_agents ( ) ;
}
} else if ( p - > dead ) {
if ( p - > dead ) {
ast_channel_lock ( p - > chan ) ;
ast_softhangup ( p - > chan , AST_SOFTHANGUP_EXPLICIT ) ;
ast_channel_unlock ( p - > chan ) ;
@ -961,10 +876,7 @@ static int agent_hangup(struct ast_channel *ast)
/* Only register a device state change if the agent is still logged in */
if ( ! p - > loginstart ) {
p - > loginchan [ 0 ] = ' \0 ' ;
p - > logincallerid [ 0 ] = ' \0 ' ;
if ( persistent_agents )
dump_agents ( ) ;
} else {
ast_devstate_changed ( AST_DEVICE_NOT_INUSE , " Agent/%s " , p - > agent ) ;
}
@ -992,10 +904,8 @@ static int agent_hangup(struct ast_channel *ast)
ast_mutex_unlock ( & p - > lock ) ;
}
/* Release ownership of the agent to other threads (presumably running the login app). */
if ( ast_strlen_zero ( p - > loginchan ) ) {
p - > app_lock_flag = 0 ;
ast_cond_signal ( & p - > app_complete_cond ) ;
}
p - > app_lock_flag = 0 ;
ast_cond_signal ( & p - > app_complete_cond ) ;
}
return 0 ;
}
@ -1132,7 +1042,7 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
alreadylocked = p - > app_lock_flag ;
p - > app_lock_flag = 1 ;
if ( ast_strlen_zero ( p - > loginchan ) & & alreadylocked ) {
if ( alreadylocked ) {
if ( p - > chan ) {
ast_queue_frame ( p - > chan , & ast_null_frame ) ;
ast_mutex_unlock ( & p - > lock ) ; /* For other thread to read the condition. */
@ -1149,18 +1059,6 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
ast_cond_signal ( & p - > app_complete_cond ) ;
return NULL ;
}
} else if ( ! ast_strlen_zero ( p - > loginchan ) ) {
if ( p - > chan )
ast_queue_frame ( p - > chan , & ast_null_frame ) ;
if ( ! p - > chan ) {
ast_log ( LOG_WARNING , " Agent disconnected while we were connecting the call \n " ) ;
p - > owner = NULL ;
tmp - > tech_pvt = NULL ;
p - > app_sleep_cond = 1 ;
tmp = ast_channel_release ( tmp ) ;
ast_mutex_unlock ( & p - > lock ) ; /* For other thread to read the condition. */
return NULL ;
}
}
if ( p - > chan )
ast_indicate ( p - > chan , AST_CONTROL_UNHOLD ) ;
@ -1179,7 +1077,6 @@ static int read_agent_config(int reload)
struct ast_config * ucfg ;
struct ast_variable * v ;
struct agent_pvt * p ;
const char * general_val ;
const char * catname ;
const char * hasagent ;
int genhasagent ;
@ -1222,8 +1119,6 @@ static int read_agent_config(int reload)
savecallsin [ 0 ] = ' \0 ' ;
/* Read in [general] section for persistence */
if ( ( general_val = ast_variable_retrieve ( cfg , " general " , " persistentagents " ) ) )
persistent_agents = ast_true ( general_val ) ;
multiplelogin = ast_true ( ast_variable_retrieve ( cfg , " general " , " multiplelogin " ) ) ;
/* Read in the [agents] section */
@ -1239,12 +1134,9 @@ static int read_agent_config(int reload)
if ( autologoff < 0 )
autologoff = 0 ;
} else if ( ! strcasecmp ( v - > name , " ackcall " ) ) {
if ( ! strcasecmp ( v - > value , " always " ) )
ackcall = 2 ;
else if ( ast_true ( v - > value ) )
if ( ast_true ( v - > value ) | | ! strcasecmp ( v - > value , " always " ) ) {
ackcall = 1 ;
else
ackcall = 0 ;
}
} else if ( ! strcasecmp ( v - > name , " endcall " ) ) {
endcall = ast_true ( v - > value ) ;
} else if ( ! strcasecmp ( v - > name , " acceptdtmf " ) ) {
@ -1371,7 +1263,7 @@ static int check_availability(struct agent_pvt *newlyavailable, int needlock)
if ( needlock )
AST_LIST_UNLOCK ( & agents ) ;
if ( parent & & chan ) {
if ( newlyavailable - > ackcall > 1 ) {
if ( newlyavailable - > ackcall ) {
/* Don't do beep here */
res = 0 ;
} else {
@ -1469,8 +1361,7 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
AST_LIST_LOCK ( & agents ) ;
AST_LIST_TRAVERSE ( & agents , p , list ) {
ast_mutex_lock ( & p - > lock ) ;
if ( ! p - > pending & & ( ( groupmatch & & ( p - > group & groupmatch ) ) | | ! strcmp ( data , p - > agent ) ) & &
ast_strlen_zero ( p - > loginchan ) ) {
if ( ! p - > pending & & ( ( groupmatch & & ( p - > group & groupmatch ) ) | | ! strcmp ( data , p - > agent ) ) ) {
if ( p - > chan )
hasagent + + ;
now = ast_tvnow ( ) ;
@ -1493,23 +1384,16 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
AST_LIST_TRAVERSE ( & agents , p , list ) {
ast_mutex_lock ( & p - > lock ) ;
if ( ! p - > pending & & ( ( groupmatch & & ( p - > group & groupmatch ) ) | | ! strcmp ( data , p - > agent ) ) ) {
if ( p - > chan | | ! ast_strlen_zero ( p - > loginchan ) )
if ( p - > chan ) {
hasagent + + ;
}
now = ast_tvnow ( ) ;
#if 0
ast_log ( LOG_NOTICE , " Time now: %ld, Time of lastdisc: %ld \n " , now . tv_sec , p - > lastdisc . tv_sec ) ;
# endif
if ( ! p - > lastdisc . tv_sec | | ( now . tv_sec > = p - > lastdisc . tv_sec ) ) {
p - > lastdisc = ast_tv ( 0 , 0 ) ;
/* Agent must be registered, but not have any active call, and not be in a waiting state */
if ( ! p - > owner & & p - > chan ) {
/* Could still get a fixed agent */
chan = agent_new ( p , AST_STATE_DOWN ) ;
} else if ( ! p - > owner & & ! ast_strlen_zero ( p - > loginchan ) ) {
/* Adjustable agent */
p - > chan = ast_request ( " Local " , format , p - > loginchan , cause ) ;
if ( p - > chan )
chan = agent_new ( p , AST_STATE_DOWN ) ;
}
if ( chan ) {
ast_mutex_unlock ( & p - > lock ) ;
@ -1562,7 +1446,6 @@ static int action_agents(struct mansession *s, const struct message *m)
{
const char * id = astman_get_header ( m , " ActionID " ) ;
char idText [ 256 ] = " " ;
char chanbuf [ 256 ] ;
struct agent_pvt * p ;
char * username = NULL ;
char * loginChan = NULL ;
@ -1588,16 +1471,7 @@ static int action_agents(struct mansession *s, const struct message *m)
/* Set a default status. It 'should' get changed. */
status = " AGENT_UNKNOWN " ;
if ( ! ast_strlen_zero ( p - > loginchan ) & & ! p - > chan ) {
loginChan = p - > loginchan ;
talkingto = " n/a " ;
talkingtoChan = " n/a " ;
status = " AGENT_IDLE " ;
if ( p - > acknowledged ) {
snprintf ( chanbuf , sizeof ( chanbuf ) , " %s (Confirmed) " , p - > loginchan ) ;
loginChan = chanbuf ;
}
} else if ( p - > chan ) {
if ( p - > chan ) {
loginChan = ast_strdupa ( p - > chan - > name ) ;
if ( p - > owner & & p - > owner - > _bridge ) {
talkingto = p - > chan - > cid . cid_num ;
@ -1638,49 +1512,9 @@ static int action_agents(struct mansession *s, const struct message *m)
return 0 ;
}
static void agent_logoff_maintenance ( struct agent_pvt * p , char * loginchan , long logintime , const char * uniqueid , char * logcommand )
{
char * tmp = NULL ;
char agent [ AST_MAX_AGENT ] ;
if ( ! ast_strlen_zero ( logcommand ) )
tmp = logcommand ;
else
tmp = ast_strdupa ( " " ) ;
snprintf ( agent , sizeof ( agent ) , " Agent/%s " , p - > agent ) ;
if ( ! ast_strlen_zero ( uniqueid ) ) {
manager_event ( EVENT_FLAG_AGENT , " Agentcallbacklogoff " ,
" Agent: %s \r \n "
" Reason: %s \r \n "
" Loginchan: %s \r \n "
" Logintime: %ld \r \n "
" Uniqueid: %s \r \n " ,
p - > agent , tmp , loginchan , logintime , uniqueid ) ;
} else {
manager_event ( EVENT_FLAG_AGENT , " Agentcallbacklogoff " ,
" Agent: %s \r \n "
" Reason: %s \r \n "
" Loginchan: %s \r \n "
" Logintime: %ld \r \n " ,
p - > agent , tmp , loginchan , logintime ) ;
}
ast_queue_log ( " NONE " , ast_strlen_zero ( uniqueid ) ? " NONE " : uniqueid , agent , " AGENTCALLBACKLOGOFF " , " %s|%ld|%s " , loginchan , logintime , tmp ) ;
set_agentbycallerid ( p - > logincallerid , NULL ) ;
p - > loginchan [ 0 ] = ' \0 ' ;
p - > logincallerid [ 0 ] = ' \0 ' ;
ast_devstate_changed ( AST_DEVICE_UNAVAILABLE , " Agent/%s " , p - > agent ) ;
if ( persistent_agents )
dump_agents ( ) ;
}
static int agent_logoff ( const char * agent , int soft )
{
struct agent_pvt * p ;
long logintime ;
int ret = - 1 ; /* Return -1 if no agent if found */
AST_LIST_LOCK ( & agents ) ;
@ -1710,10 +1544,6 @@ static int agent_logoff(const char *agent, int soft)
ast_mutex_unlock ( & p - > lock ) ;
} else
p - > deferlogoff = 1 ;
} else {
logintime = time ( NULL ) - p - > loginstart ;
p - > loginstart = 0 ;
agent_logoff_maintenance ( p , p - > loginchan , logintime , NULL , " CommandLogoff " ) ;
}
break ;
}
@ -1855,15 +1685,6 @@ static char *agents_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
else
strcpy ( talkingto , " is idle " ) ;
online_agents + + ;
} else if ( ! ast_strlen_zero ( p - > loginchan ) ) {
if ( ast_tvdiff_ms ( ast_tvnow ( ) , p - > lastdisc ) > 0 | | ! ( p - > lastdisc . tv_sec ) )
snprintf ( location , sizeof ( location ) - 20 , " available at '%s' " , p - > loginchan ) ;
else
snprintf ( location , sizeof ( location ) - 20 , " wrapping up at '%s' " , p - > loginchan ) ;
talkingto [ 0 ] = ' \0 ' ;
online_agents + + ;
if ( p - > acknowledged )
strncat ( location , " (Confirmed) " , sizeof ( location ) - strlen ( location ) - 1 ) ;
} else {
strcpy ( location , " not logged in " ) ;
talkingto [ 0 ] = ' \0 ' ;
@ -1929,13 +1750,6 @@ static char *agents_show_online(struct ast_cli_entry *e, int cmd, struct ast_cli
strcpy ( talkingto , " is idle " ) ;
agent_status = 1 ;
online_agents + + ;
} else if ( ! ast_strlen_zero ( p - > loginchan ) ) {
snprintf ( location , sizeof ( location ) - 20 , " available at '%s' " , p - > loginchan ) ;
talkingto [ 0 ] = ' \0 ' ;
agent_status = 1 ;
online_agents + + ;
if ( p - > acknowledged )
strncat ( location , " (Confirmed) " , sizeof ( location ) - strlen ( location ) - 1 ) ;
}
if ( ! ast_strlen_zero ( p - > moh ) )
snprintf ( music , sizeof ( music ) , " (musiconhold is '%s') " , p - > moh ) ;
@ -2083,12 +1897,11 @@ static int login_exec(struct ast_channel *chan, const char *data)
/* Set Channel Specific Agent Overrides */
if ( ! ast_strlen_zero ( pbx_builtin_getvar_helper ( chan , " AGENTACKCALL " ) ) ) {
if ( ! strcasecmp ( pbx_builtin_getvar_helper ( chan , " AGENTACKCALL " ) , " always " ) )
p - > ackcall = 2 ;
else if ( ast_true ( pbx_builtin_getvar_helper ( chan , " AGENTACKCALL " ) ) )
if ( ast_true ( pbx_builtin_getvar_helper ( chan , " AGENTACKCALL " ) ) ) {
p - > ackcall = 1 ;
else
} else {
p - > ackcall = 0 ;
}
tmpoptions = pbx_builtin_getvar_helper ( chan , " AGENTACKCALL " ) ;
ast_verb ( 3 , " Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'. \n " , tmpoptions , p - > ackcall , p - > agent ) ;
ast_set_flag ( p , AGENT_FLAG_ACKCALL ) ;
@ -2134,7 +1947,6 @@ static int login_exec(struct ast_channel *chan, const char *data)
long logintime ;
snprintf ( agent , sizeof ( agent ) , " Agent/%s " , p - > agent ) ;
p - > loginchan [ 0 ] = ' \0 ' ;
p - > logincallerid [ 0 ] = ' \0 ' ;
p - > acknowledged = 0 ;
@ -2177,10 +1989,11 @@ static int login_exec(struct ast_channel *chan, const char *data)
ast_getformatname ( chan - > readformat ) , ast_getformatname ( chan - > writeformat ) ) ;
/* Login this channel and wait for it to go away */
p - > chan = chan ;
if ( p - > ackcall > 1 )
if ( p - > ackcall ) {
check_beep ( p , 0 ) ;
else
} else {
check_availability ( p , 0 ) ;
}
ast_mutex_unlock ( & p - > lock ) ;
AST_LIST_UNLOCK ( & agents ) ;
ast_devstate_changed ( AST_DEVICE_NOT_INUSE , " Agent/%s " , p - > agent ) ;
@ -2205,10 +2018,11 @@ static int login_exec(struct ast_channel *chan, const char *data)
ast_debug ( 1 , " Wrapup time for %s expired! \n " , p - > agent ) ;
p - > lastdisc = ast_tv ( 0 , 0 ) ;
ast_devstate_changed ( AST_DEVICE_NOT_INUSE , " Agent/%s " , p - > agent ) ;
if ( p - > ackcall > 1 )
if ( p - > ackcall ) {
check_beep ( p , 0 ) ;
else
} else {
check_availability ( p , 0 ) ;
}
}
}
ast_mutex_unlock ( & p - > lock ) ;
@ -2221,11 +2035,12 @@ static int login_exec(struct ast_channel *chan, const char *data)
ast_mutex_unlock ( & p - > app_lock ) ;
ast_mutex_lock ( & p - > lock ) ;
ast_mutex_unlock ( & p - > lock ) ;
if ( p - > ackcall > 1 )
if ( p - > ackcall ) {
res = agent_ack_sleep ( p ) ;
else
} else {
res = ast_safe_sleep_conditional ( chan , 1000 , agent_cont_sleep , p ) ;
if ( ( p - > ackcall > 1 ) & & ( res = = 1 ) ) {
}
if ( p - > ackcall & & ( res = = 1 ) ) {
AST_LIST_LOCK ( & agents ) ;
ast_mutex_lock ( & p - > lock ) ;
check_availability ( p , 0 ) ;
@ -2352,84 +2167,6 @@ static int agentmonitoroutgoing_exec(struct ast_channel *chan, const char *data)
return 0 ;
}
/*!
* \ brief Dump AgentCallbackLogin agents to the ASTdb database for persistence
*/
static void dump_agents ( void )
{
struct agent_pvt * cur_agent = NULL ;
char buf [ 256 ] ;
AST_LIST_TRAVERSE ( & agents , cur_agent , list ) {
if ( cur_agent - > chan )
continue ;
if ( ! ast_strlen_zero ( cur_agent - > loginchan ) ) {
snprintf ( buf , sizeof ( buf ) , " %s;%s " , cur_agent - > loginchan , cur_agent - > logincallerid ) ;
if ( ast_db_put ( pa_family , cur_agent - > agent , buf ) )
ast_log ( LOG_WARNING , " failed to create persistent entry in ASTdb for %s! \n " , buf ) ;
else
ast_debug ( 1 , " Saved Agent: %s on %s \n " , cur_agent - > agent , cur_agent - > loginchan ) ;
} else {
/* Delete - no agent or there is an error */
ast_db_del ( pa_family , cur_agent - > agent ) ;
}
}
}
/*!
* \ brief Reload the persistent agents from astdb .
*/
static void reload_agents ( void )
{
char * agent_num ;
struct ast_db_entry * db_tree ;
struct ast_db_entry * entry ;
struct agent_pvt * cur_agent ;
char agent_data [ 256 ] ;
char * parse ;
char * agent_chan ;
char * agent_callerid ;
db_tree = ast_db_gettree ( pa_family , NULL ) ;
AST_LIST_LOCK ( & agents ) ;
for ( entry = db_tree ; entry ; entry = entry - > next ) {
agent_num = entry - > key + strlen ( pa_family ) + 2 ;
AST_LIST_TRAVERSE ( & agents , cur_agent , list ) {
ast_mutex_lock ( & cur_agent - > lock ) ;
if ( strcmp ( agent_num , cur_agent - > agent ) = = 0 )
break ;
ast_mutex_unlock ( & cur_agent - > lock ) ;
}
if ( ! cur_agent ) {
ast_db_del ( pa_family , agent_num ) ;
continue ;
} else
ast_mutex_unlock ( & cur_agent - > lock ) ;
if ( ! ast_db_get ( pa_family , agent_num , agent_data , sizeof ( agent_data ) - 1 ) ) {
ast_debug ( 1 , " Reload Agent from AstDB: %s on %s \n " , cur_agent - > agent , agent_data ) ;
parse = agent_data ;
agent_chan = strsep ( & parse , " ; " ) ;
agent_callerid = strsep ( & parse , " ; " ) ;
ast_copy_string ( cur_agent - > loginchan , agent_chan , sizeof ( cur_agent - > loginchan ) ) ;
if ( agent_callerid ) {
ast_copy_string ( cur_agent - > logincallerid , agent_callerid , sizeof ( cur_agent - > logincallerid ) ) ;
set_agentbycallerid ( cur_agent - > logincallerid , cur_agent - > agent ) ;
} else
cur_agent - > logincallerid [ 0 ] = ' \0 ' ;
if ( cur_agent - > loginstart = = 0 )
time ( & cur_agent - > loginstart ) ;
ast_devstate_changed ( AST_DEVICE_UNKNOWN , " Agent/%s " , cur_agent - > agent ) ;
}
}
AST_LIST_UNLOCK ( & agents ) ;
if ( db_tree ) {
ast_log ( LOG_NOTICE , " Agents successfully reloaded from database. \n " ) ;
ast_db_freetree ( db_tree ) ;
}
}
/*! \brief Part of PBX channel interface */
static int agent_devicestate ( void * data )
{
@ -2458,7 +2195,7 @@ static int agent_devicestate(void *data)
} else {
if ( res = = AST_DEVICE_BUSY )
res = AST_DEVICE_INUSE ;
if ( p - > chan | | ! ast_strlen_zero ( p - > loginchan ) ) {
if ( p - > chan ) {
if ( res = = AST_DEVICE_INVALID )
res = AST_DEVICE_UNKNOWN ;
} else if ( res = = AST_DEVICE_INVALID )
@ -2523,8 +2260,9 @@ static int function_agent(struct ast_channel *chan, const char *cmd, char *data,
if ( ! strcasecmp ( args . item , " status " ) ) {
char * status = " LOGGEDOUT " ;
if ( agent - > chan | | ! ast_strlen_zero ( agent - > loginchan ) )
status = " LOGGEDIN " ;
if ( agent - > chan ) {
status = " LOGGEDIN " ;
}
ast_copy_string ( buf , status , len ) ;
} else if ( ! strcasecmp ( args . item , " password " ) )
ast_copy_string ( buf , agent - > password , len ) ;
@ -2539,8 +2277,9 @@ static int function_agent(struct ast_channel *chan, const char *cmd, char *data,
if ( tmp )
* tmp = ' \0 ' ;
}
} else if ( ! strcasecmp ( args . item , " exten " ) )
ast_copy_string ( buf , agent - > loginchan , len ) ;
} else if ( ! strcasecmp ( args . item , " exten " ) ) {
buf [ 0 ] = ' \0 ' ;
}
AST_LIST_UNLOCK ( & agents ) ;
@ -2570,8 +2309,6 @@ static int load_module(void)
/* Read in the config */
if ( ! read_agent_config ( 0 ) )
return AST_MODULE_LOAD_DECLINE ;
if ( persistent_agents )
reload_agents ( ) ;
/* Dialplan applications */
ast_register_application_xml ( app , login_exec ) ;
ast_register_application_xml ( app3 , agentmonitoroutgoing_exec ) ;
@ -2591,11 +2328,7 @@ static int load_module(void)
static int reload ( void )
{
if ( ! read_agent_config ( 1 ) ) {
if ( persistent_agents )
reload_agents ( ) ;
}
return 0 ;
return read_agent_config ( 1 ) ;
}
static int unload_module ( void )