Index: channels/chan_dahdi.c
===================================================================
--- channels/chan_dahdi.c (revision 241226)
+++ channels/chan_dahdi.c (working copy)
@@ -11623,7 +11623,7 @@
tmp->callgroup = conf->chan.callgroup;
tmp->pickupgroup= conf->chan.pickupgroup;
if (conf->chan.vars) {
- tmp->vars = ast_variable_new(conf->chan.vars->name, conf->chan.vars->value, "");
+ tmp->vars = conf->chan.vars;
}
tmp->cid_rxgain = conf->chan.cid_rxgain;
tmp->rxgain = conf->chan.rxgain;
Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c (revision 241226)
+++ channels/chan_sip.c (working copy)
@@ -15322,8 +15322,8 @@
struct ao2_iterator i;
/* the last argument is left-aligned, so we don't need a size anyways */
-#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
-#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
+#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-10.10s %-3.3s %-8s %-17s %s %s\n"
+#define FORMAT "%-25.25s %-15.15s %-3.3s %-10.10s %-3.3s %-8d %-17s %s %s\n"
char name[256];
int total_peers = 0;
@@ -15363,7 +15363,7 @@
}
if (!s) /* Normal list */
- ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
+ ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""), "Callerid");
i = ao2_iterator_init(peers, 0);
@@ -15393,6 +15393,7 @@
for(k=0; k < total_peers; k++) {
char status[20] = "";
char srch[2000];
+ char cbuf[256];
char pstatus;
peer = peerarray[k];
@@ -15426,7 +15427,8 @@
ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */
ntohs(peer->addr.sin_port), status,
- realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
+ realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "",
+ ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
if (!s) {/* Normal CLI list */
ast_cli(fd, FORMAT, name,
@@ -15434,9 +15436,9 @@
peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */
-
ntohs(peer->addr.sin_port), status,
- realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
+ realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "",
+ ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
} else { /* Manager format */
/* The names here need to be the same as other channels */
astman_append(s,
@@ -15452,7 +15454,8 @@
"TextSupport: %s\r\n"
"ACL: %s\r\n"
"Status: %s\r\n"
- "RealtimeDevice: %s\r\n\r\n",
+ "RealtimeDevice: %s\r\n"
+ "Callerid: %s\r\n\r\n",
idtext,
peer->name,
peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
@@ -15463,7 +15466,8 @@
ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */
peer->ha ? "yes" : "no", /* permit/deny */
status,
- realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
+ realtimepeers ? (peer->is_realtime ? "yes":"no") : "no",
+ ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
}
ao2_unlock(peer);
unref_peer(peer, "toss iterator peer ptr");
@@ -17403,10 +17407,21 @@
} else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
/* Client code (from SNOM phone) */
if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
- if (p->owner && p->owner->cdr)
- ast_cdr_setuserfield(p->owner, c);
- if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
- ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
+ struct ast_channel *chan = p->owner;
+
+ if (chan) {
+ pbx_builtin_setvar_helper(chan, "SIPCLIENTCODE", c);
+ manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
+ "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nX-ClientCode: %s\r\n",
+ chan->name, "SIP", chan->uniqueid, c);
+ if (chan->cdr) {
+ ast_cdr_setuserfield(chan, c);
+ }
+ chan = ast_bridged_channel(p->owner);
+ if (chan && chan->cdr) {
+ ast_cdr_setuserfield(chan, c);
+ }
+ }
transmit_response(p, "200 OK", req);
} else {
transmit_response(p, "403 Forbidden", req);
Index: apps/app_directed_pickup.c
===================================================================
--- apps/app_directed_pickup.c (revision 241226)
+++ apps/app_directed_pickup.c (working copy)
@@ -79,6 +79,13 @@
+
+
+
+
+
This will pickup a specified channel if ringing.
@@ -303,24 +310,65 @@
return res;
}
+/* Find channel for pick up specified by partial channel name */
+static int find_by_part(void *obj, void *arg, void *data, int flags)
+{
+ struct ast_channel *c = obj;
+ const char *part = data;
+ int res;
+
+ ast_channel_lock(c);
+ res = (!memcmp(c->name, part, strlen(part))) && can_pickup(c);
+ ast_channel_unlock(c);
+
+ return res ? CMP_MATCH | CMP_STOP : 0;
+}
+
+/* Attempt to pick up specified by partial channel name */
+static int pickup_by_part(struct ast_channel *chan, const char *part)
+{
+ struct ast_channel *target;
+ int res = -1;
+
+ if ((target = ast_channel_callback(find_by_part, NULL, (char *) part, 0))) {
+ ast_channel_lock(target);
+ res = pickup_do(chan, target);
+ ast_channel_unlock(target);
+ target = ast_channel_unref(target);
+ }
+
+ return res;
+}
+
/* application entry point for PickupChan() */
static int pickupchan_exec(struct ast_channel *chan, const char *data)
{
int res = 0;
- char *tmp = ast_strdupa(data);
char *pickup = NULL;
+ char *parse;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(channel);
+ AST_APP_ARG(options);
+ );
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
- if (ast_strlen_zero(data)) {
+ if (ast_strlen_zero(args.channel)) {
ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n");
return -1;
}
/* Parse channel */
- while (!ast_strlen_zero(tmp) && (pickup = strsep(&tmp, "&"))) {
+ while (!ast_strlen_zero(args.channel) && (pickup = strsep(&args.channel, "&"))) {
if (!strncasecmp(chan->name, pickup, strlen(pickup))) {
ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup);
} else {
- if (!pickup_by_channel(chan, pickup)) {
+ if (!strcmp(args.options, "p")) {
+ if (!pickup_by_part(chan, pickup)) {
+ break;
+ }
+ }
+ else if (!pickup_by_channel(chan, pickup)) {
break;
}
ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup);
Index: apps/app_dial.c
===================================================================
--- apps/app_dial.c (revision 241226)
+++ apps/app_dial.c (working copy)
@@ -798,6 +798,18 @@
/* Before processing channel, go ahead and check for forwarding */
ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
+ manager_event(EVENT_FLAG_CALL, "Forward",
+ "Channel: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Destination: %s/%s\r\n"
+ "Via: %s\r\n",
+ in->name, in->uniqueid,
+ in->cid.cid_num ? in->cid.cid_num : "unknown",
+ in->cid.cid_name ? in->cid.cid_name : "unknown",
+ tech, stuff,
+ c->name);
/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
Index: apps/app_queue.c
===================================================================
--- apps/app_queue.c (revision 241226)
+++ apps/app_queue.c (working copy)
@@ -724,6 +724,9 @@
/* The maximum length of each persistent member queue database entry */
#define PM_MAX_LEN 8192
+/*! \brief queues.conf keep statistics on reoads option */
+static int queue_keep_stats = 0;
+
/*! \brief queues.conf [general] option */
static int queue_persistent_members = 0;
@@ -1366,13 +1369,11 @@
}
/*! \brief allocate space for new queue member and set fields based on parameters passed */
-static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface)
+static struct member *create_queue_member(const char *interface, const char *membername, const char *state_interface)
{
struct member *cur;
if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
- cur->penalty = penalty;
- cur->paused = paused;
ast_copy_string(cur->interface, interface, sizeof(cur->interface));
if (!ast_strlen_zero(state_interface))
ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface));
@@ -1890,9 +1891,11 @@
/* Create a new member */
if (!found) {
- if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
+ if ((m = create_queue_member(interface, membername, state_interface))) {
m->dead = 0;
m->realtime = 1;
+ m->penalty = penalty;
+ m->paused = paused;
ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
ast_queue_log(q->name, "REALTIME", m->interface, "ADDMEMBER", "%s", "");
ao2_link(q->members, m);
@@ -4893,7 +4896,9 @@
ao2_lock(q);
if ((old_member = interface_exists(q, interface)) == NULL) {
- if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface))) {
+ if ((new_member = create_queue_member(interface, membername, state_interface))) {
+ new_member->penalty = penalty;
+ new_member->paused = paused;
new_member->dynamic = 1;
ao2_link(q->members, new_member);
q->membercount++;
@@ -6151,6 +6156,9 @@
static void queue_set_global_params(struct ast_config *cfg)
{
const char *general_val = NULL;
+ queue_keep_stats = 0;
+ if ((general_val = ast_variable_retrieve(cfg, "general", "keepstats")))
+ queue_keep_stats = ast_true(general_val);
queue_persistent_members = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers")))
queue_persistent_members = ast_true(general_val);
@@ -6231,7 +6239,16 @@
/* Find the old position in the list */
ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
cur = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK);
- if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface))) {
+ if ((newm = create_queue_member(interface, membername, state_interface))) {
+ newm->penalty = penalty;
+ if (cur) {
+ newm->paused = cur->paused;
+ newm->status = cur->status;
+ newm->lastcall = cur->lastcall;
+ if (queue_keep_stats) {
+ newm->calls = cur->calls;
+ }
+ }
ao2_link(q->members, newm);
ao2_ref(newm, -1);
}
@@ -7068,6 +7085,9 @@
if (!header_found) {
ast_set_flag(&mask, AST_FLAGS_ALL);
+ if (queue_keep_stats) {
+ ast_clear_flag(&mask, QUEUE_RESET_STATS);
+ }
}
if (!reload_handler(1, &mask, queuename)) {
@@ -7586,6 +7606,9 @@
ast_set_flag(&mask, QUEUE_RELOAD_PARAMETERS);
} else if (!strcasecmp(a->argv[2], "all")) {
ast_set_flag(&mask, AST_FLAGS_ALL);
+ if (queue_keep_stats) {
+ ast_clear_flag(&mask, QUEUE_RESET_STATS);
+ }
}
if (a->argc == 3) {
@@ -7738,6 +7761,10 @@
static int reload(void)
{
struct ast_flags mask = {AST_FLAGS_ALL,};
+
+ if (queue_keep_stats) {
+ ast_clear_flag(&mask, QUEUE_RESET_STATS);
+ }
ast_unload_realtime("queue_members");
reload_handler(1, &mask, NULL);
return 0;