mirror of https://github.com/sipwise/asterisk.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
6.3 KiB
183 lines
6.3 KiB
--- apps/app_queue.c (revisión: 131)
|
|
+++ apps/app_queue.c (copia de trabajo)
|
|
@@ -287,6 +287,8 @@
|
|
/*! \brief queues.conf [general] option */
|
|
static int montype_default = 0;
|
|
|
|
+
|
|
+
|
|
enum queue_result {
|
|
QUEUE_UNKNOWN = 0,
|
|
QUEUE_TIMEOUT = 1,
|
|
@@ -401,6 +403,7 @@
|
|
unsigned int leavewhenempty:2;
|
|
unsigned int ringinuse:1;
|
|
unsigned int setinterfacevar:1;
|
|
+ unsigned int setqueuevar:1;
|
|
unsigned int reportholdtime:1;
|
|
unsigned int wrapped:1;
|
|
unsigned int timeoutrestart:1;
|
|
@@ -459,8 +462,69 @@
|
|
|
|
static int set_member_paused(const char *queuename, const char *interface, int paused);
|
|
|
|
-static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
|
|
+static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
|
|
|
|
+static char *int2strat(int strategy);
|
|
+
|
|
+static inline struct call_queue *queue_ref(struct call_queue *q)
|
|
+{
|
|
+ ao2_ref(q, 1);
|
|
+ return q;
|
|
+}
|
|
+
|
|
+static inline struct call_queue *queue_unref(struct call_queue *q)
|
|
+{
|
|
+ ao2_ref(q, -1);
|
|
+ return q;
|
|
+}
|
|
+
|
|
+static void set_queue_variables(struct call_queue *q, struct ast_channel *chan)
|
|
+{
|
|
+
|
|
+ char interfacevar[256]="";
|
|
+ float sl = 0;
|
|
+
|
|
+ if (q->setqueuevar) {
|
|
+ sl = 0;
|
|
+ if (q->callscompleted > 0)
|
|
+ sl = 100 * ((float) q->callscompletedinsl / (float) q->callscompleted);
|
|
+
|
|
+ snprintf(interfacevar, sizeof(interfacevar),
|
|
+ "QUEUENAME=%s,QUEUEMAX=%d,QUEUESTRATEGY=%s,QUEUECALLS=%d,QUEUEHOLDTIME=%d,QUEUECOMPLETED=%d,QUEUEABANDONED=%d,QUEUESRVLEVEL=%d,QUEUESRVLEVELPERF=%2.1f",
|
|
+ q->name, q->maxlen, int2strat(q->strategy), q->count, q->holdtime, q->callscompleted, q->callsabandoned, q->servicelevel, sl);
|
|
+
|
|
+ pbx_builtin_setvar_multiple(chan, interfacevar);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+struct queue_end_bridge {
|
|
+ struct call_queue *q;
|
|
+ struct ast_channel *chan;
|
|
+};
|
|
+
|
|
+static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
|
|
+{
|
|
+ struct queue_end_bridge *qeb = bconfig->end_bridge_callback_data;
|
|
+ ao2_ref(qeb, +1);
|
|
+ qeb->chan = originator;
|
|
+
|
|
+}
|
|
+ static void end_bridge_callback(void *data)
|
|
+ {
|
|
+ struct queue_end_bridge *qeb = data;
|
|
+ struct call_queue *q = qeb->q;
|
|
+ struct ast_channel *chan = qeb->chan;
|
|
+
|
|
+ if (ao2_ref(qeb, -1) == 1) {
|
|
+ ao2_lock(q);
|
|
+ set_queue_variables(q, chan);
|
|
+ ao2_unlock(q);
|
|
+ /* This unrefs the reference we made in try_calling when we allocated qeb */
|
|
+ queue_unref(q);
|
|
+ }
|
|
+ }
|
|
+
|
|
static void rr_dep_warning(void)
|
|
{
|
|
static unsigned int warned = 0;
|
|
@@ -2830,6 +2894,7 @@
|
|
int callcompletedinsl;
|
|
struct ao2_iterator memi;
|
|
struct ast_datastore *datastore, *transfer_ds;
|
|
+ struct queue_end_bridge *queue_end_bridge = NULL;
|
|
|
|
ast_channel_lock(qe->chan);
|
|
datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
|
|
@@ -3256,6 +3321,19 @@
|
|
|
|
if (member->status == AST_DEVICE_NOT_INUSE)
|
|
ast_log(LOG_WARNING, "The device state of this queue member, %s, is still 'Not in Use' when it probably should not be! Please check UPGRADE.txt for correct configuration settings.\n", member->membername);
|
|
+
|
|
+ if ((queue_end_bridge = ao2_alloc(sizeof(*queue_end_bridge), NULL))) {
|
|
+ queue_end_bridge->q = qe->parent;
|
|
+ queue_end_bridge->chan = qe->chan;
|
|
+ bridge_config.end_bridge_callback = end_bridge_callback;
|
|
+ bridge_config.end_bridge_callback_data = queue_end_bridge;
|
|
+ bridge_config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
|
|
+ /* Since queue_end_bridge can survive beyond the life of this call to Queue, we need
|
|
+ * to make sure to increase the refcount of this queue so it cannot be freed until we
|
|
+ * are done with it. We remove this reference in end_bridge_callback.
|
|
+ */
|
|
+ queue_ref(qe->parent);
|
|
+ }
|
|
|
|
transfer_ds = setup_transfer_datastore(qe, member, callstart, callcompletedinsl);
|
|
bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
|
|
--- include/asterisk/pbx.h (revisión: 131)
|
|
+++ include/asterisk/pbx.h (copia de trabajo)
|
|
@@ -886,6 +886,7 @@
|
|
* \note Will lock the channel.
|
|
*/
|
|
int pbx_builtin_setvar(struct ast_channel *chan, void *data);
|
|
+int pbx_builtin_setvar_multiple(struct ast_channel *chan, void *data);
|
|
|
|
void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
|
|
void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count);
|
|
--- main/pbx.c (revisión: 131)
|
|
+++ main/pbx.c (copia de trabajo)
|
|
@@ -236,6 +236,7 @@
|
|
static int pbx_builtin_saycharacters(struct ast_channel *, void *);
|
|
static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
|
|
int pbx_builtin_setvar(struct ast_channel *, void *);
|
|
+int pbx_builtin_setvar_multiple(struct ast_channel *, void *);
|
|
static int pbx_builtin_importvar(struct ast_channel *, void *);
|
|
|
|
AST_MUTEX_DEFINE_STATIC(globalslock);
|
|
@@ -5938,6 +5939,43 @@
|
|
ast_mutex_unlock(&globalslock);
|
|
}
|
|
|
|
+int pbx_builtin_setvar_multiple(struct ast_channel *chan, void *vdata)
|
|
+{
|
|
+ char *data;
|
|
+ int x;
|
|
+ AST_DECLARE_APP_ARGS(args,
|
|
+ AST_APP_ARG(pair)[24];
|
|
+ );
|
|
+ AST_DECLARE_APP_ARGS(pair,
|
|
+ AST_APP_ARG(name);
|
|
+ AST_APP_ARG(value);
|
|
+ );
|
|
+
|
|
+ if (ast_strlen_zero(vdata)) {
|
|
+ ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ data = ast_strdupa(vdata);
|
|
+ AST_STANDARD_APP_ARGS(args, data);
|
|
+
|
|
+ for (x = 0; x < args.argc; x++) {
|
|
+ AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '=');
|
|
+ if (pair.argc == 2) {
|
|
+ pbx_builtin_setvar_helper(chan, pair.name, pair.value);
|
|
+ if (strchr(pair.name, ' '))
|
|
+ ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", pair.name, pair.value);
|
|
+ } else if (!chan) {
|
|
+ ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name);
|
|
+ } else {
|
|
+ ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, chan->exten, chan->context, chan->priority);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
|
|
{
|
|
struct ast_var_t *newvariable;
|