--- 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;
