char agent[AST_MAX_AGENT]; /*!< Agent ID */
char password[AST_MAX_AGENT]; /*!< Password for Agent login */
char name[AST_MAX_AGENT];
+ int inherited_devicestate; /*!< Does the underlying channel have a devicestate to pass? */
ast_mutex_t app_lock; /**< Synchronization between owning applications */
volatile pthread_t owning_app; /**< Owning application thread id */
volatile int app_sleep_cond; /**< Sleep condition for the login app */
.set_base_channel = agent_set_base_channel,
};
+static int agent_devicestate_cb(const char *dev, int state, void *data)
+{
+ int res, i;
+ struct agent_pvt *p;
+ char basename[AST_CHANNEL_NAME], *tmp;
+
+ /* Try to be safe, but don't deadlock */
+ for (i = 0; i < 10; i++) {
+ if ((res = AST_LIST_TRYLOCK(&agents)) == 0) {
+ break;
+ }
+ }
+ if (res) {
+ return -1;
+ }
+
+ AST_LIST_TRAVERSE(&agents, p, list) {
+ ast_mutex_lock(&p->lock);
+ if (p->chan) {
+ ast_copy_string(basename, p->chan->name, sizeof(basename));
+ if ((tmp = strrchr(basename, '-'))) {
+ *tmp = '\0';
+ }
+ if (strcasecmp(p->chan->name, dev) == 0 || strcasecmp(basename, dev) == 0) {
+ p->inherited_devicestate = state;
+ ast_device_state_changed("Agent/%s", p->agent);
+ }
+ }
+ ast_mutex_unlock(&p->lock);
+ }
+ AST_LIST_UNLOCK(&agents);
+ return 0;
+}
+
/*!
* Adds an agent to the global list of agents.
*
p->app_sleep_cond = 1;
p->group = group;
p->pending = pending;
+ p->inherited_devicestate = -1;
AST_LIST_INSERT_TAIL(&agents, p, list);
}
p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
}
p->chan = NULL;
+ p->inherited_devicestate = -1;
p->acknowledged = 0;
}
} else {
} else {
/* Agent hung-up */
p->chan = NULL;
+ p->inherited_devicestate = -1;
}
if (!res) {
/* Recognize the hangup and pass it along immediately */
ast_hangup(p->chan);
p->chan = NULL;
+ p->inherited_devicestate = -1;
}
ast_log(LOG_DEBUG, "Hungup, howlong is %d, autologoff is %d\n", howlong, p->autologoff);
if ((p->deferlogoff) || (howlong && p->autologoff && (howlong > p->autologoff))) {
set_agentbycallerid(p->logincallerid, NULL);
p->loginchan[0] ='\0';
p->logincallerid[0] = '\0';
+ p->inherited_devicestate = -1;
ast_device_state_changed("Agent/%s", p->agent);
if (persistent_agents)
dump_agents();
if (res && p->owner)
ast_log(LOG_WARNING, "Huh? We broke out when there was still an owner?\n");
/* Log us off if appropriate */
- if (p->chan == chan)
+ if (p->chan == chan) {
p->chan = NULL;
+ p->inherited_devicestate = -1;
+ }
p->acknowledged = 0;
logintime = time(NULL) - p->loginstart;
p->loginstart = 0;
if (p->owner) {
if (res != AST_DEVICE_INUSE)
res = AST_DEVICE_BUSY;
+ } else if (p->inherited_devicestate > -1) {
+ res = p->inherited_devicestate;
} else {
if (res == AST_DEVICE_BUSY)
res = AST_DEVICE_INUSE;
/* Dialplan Functions */
ast_custom_function_register(&agent_function);
+ ast_devstate_add(agent_devicestate_cb, NULL);
+
return 0;
}
struct agent_pvt *p;
/* First, take us out of the channel loop */
ast_channel_unregister(&agent_tech);
+ /* Delete devicestate subscription */
+ ast_devstate_del(agent_devicestate_cb, NULL);
/* Unregister dialplan functions */
ast_custom_function_unregister(&agent_function);
/* Unregister CLI commands */