74 #include <netinet/in.h> 1429 #define DEFAULT_RETRY 5 1430 #define DEFAULT_TIMEOUT 15 1432 #define MAX_PERIODIC_ANNOUNCEMENTS 10 1437 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 1439 #define MAX_QUEUE_BUCKETS 53 1442 #define RES_EXISTS (-1) 1443 #define RES_OUTOFMEMORY (-2) 1444 #define RES_NOSUCHQUEUE (-3) 1445 #define RES_NOT_DYNAMIC (-4) 1446 #define RES_NOT_CALLER (-5) 1463 static const char *
const pm_family =
"Queue/PersistentMembers";
1506 static const struct {
1541 char interface[256];
1598 char membername[80];
1605 char reason_paused[80];
1615 char rt_uniqueid[80];
1636 #define ANNOUNCEHOLDTIME_ALWAYS 1 1637 #define ANNOUNCEHOLDTIME_ONCE 2 1638 #define QUEUE_EVENT_VARIABLES 3 1651 #define ANNOUNCEPOSITION_YES 1 1652 #define ANNOUNCEPOSITION_NO 2 1653 #define ANNOUNCEPOSITION_MORE_THAN 3 1654 #define ANNOUNCEPOSITION_LIMIT 4 1871 struct member *mem = obj;
1872 int *decrement_followers_after = arg;
1874 if (mem->
queuepos > *decrement_followers_after) {
1889 struct member *mem = obj;
1911 if (pos < queue->
rrpos) {
1918 #define queue_ref(q) ao2_bump(q) 1919 #define queue_unref(q) ({ ao2_cleanup(q); NULL; }) 1920 #define queue_t_ref(q, tag) ao2_t_bump(q, tag) 1921 #define queue_t_unref(q, tag) ({ ao2_t_cleanup(q, tag); NULL; }) 1922 #define queues_t_link(c, q, tag) ao2_t_link(c, q, tag) 1923 #define queues_t_unlink(c, q, tag) ao2_t_unlink(c, q, tag) 1928 char interfacevar[256]=
"";
1939 snprintf(interfacevar,
sizeof(interfacevar),
1940 "QUEUENAME=%s,QUEUEMAX=%d,QUEUESTRATEGY=%s,QUEUECALLS=%d,QUEUEHOLDTIME=%d,QUEUETALKTIME=%d,QUEUECOMPLETED=%d,QUEUEABANDONED=%d,QUEUESRVLEVEL=%d,QUEUESRVLEVELPERF=%2.1f",
1972 new->pos = ++(*pos);
1984 if (!channel_string || !event_string) {
2026 if (!event_string) {
2096 if (!caller_event_string) {
2105 if (!agent_event_string) {
2112 if (!event_string) {
2183 if (caller_snapshot) {
2186 ast_debug(1,
"Empty caller_snapshot; sending incomplete event\n");
2189 if (agent_snapshot) {
2214 if (!caller_snapshot || !agent_snapshot) {
2219 agent_snapshot, type, blob);
2239 if (!blob || !type) {
2260 return ast_json_pack(
"{s: s, s: s, s: s, s: s, s: s, s: i, s: i, s: i, s: i, s: i, s: i, s: i, s: s, s: i, s: i}",
2265 "Membership", (mem->
dynamic ?
"dynamic" : (mem->
realtime ?
"realtime" :
"static")),
2267 "CallsTaken", mem->
calls,
2292 int penalty = member->
penalty;
2293 if (raise_penalty != INT_MAX && penalty < raise_penalty) {
2294 ast_debug(4,
"%s is having his penalty raised up from %d to %d\n", member->
membername, penalty, raise_penalty);
2295 penalty = raise_penalty;
2297 if ((max_penalty != INT_MAX && penalty > max_penalty) || (min_penalty != INT_MAX && penalty < min_penalty)) {
2299 ast_debug(4,
"%s is unavailable because his penalty is not between %d and %d\n", member->
membername, min_penalty, max_penalty);
2307 ast_debug(4,
"%s is unavailable because his device state is 'invalid'\n", member->
membername);
2313 ast_debug(4,
"%s is unavailable because his device state is 'unavailable'\n", member->
membername);
2319 ast_debug(4,
"%s is unavailable because his device state is 'inuse'\n", member->
membername);
2325 ast_debug(4,
"%s is unavailable because his device state is 'ringing'\n", member->
membername);
2331 ast_debug(4,
"%s is unavailable because his device state is 'unknown'\n", member->
membername);
2344 ast_debug(4,
"%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n",
2362 return get_member_status(q, max_penalty, min_penalty, raise_penalty, conditions, 1);
2376 #define MAX_CALL_ATTEMPT_BUCKETS 353 2380 const struct member *object;
2389 key =
object->interface;
2400 const struct member *object_left = obj;
2401 const struct member *object_right = arg;
2402 const char *right_key = arg;
2410 cmp = strcasecmp(object_left->
interface, right_key);
2439 if (m->
status != status) {
2509 char interface[80], *slash_pos;
2519 if (dev_state->
eid) {
2532 if (!found_member) {
2535 if ((slash_pos = strchr(interface,
'/'))) {
2536 if (!strncasecmp(interface,
"Local/", 6) && (slash_pos = strchr(slash_pos + 1,
'/'))) {
2541 if (!strcasecmp(interface, dev_state->
device)) {
2551 if (avail && found_member) {
2575 ast_debug(1,
"Device '%s' changed to state '%u' (%s)\n",
2580 ast_debug(3,
"Device '%s' changed to state '%u' (%s) but we don't care because they're not a member of any queue.\n",
2661 ast_debug(1,
"Extension '%s@%s' changed to state '%d' (%s)\n", exten, context, device_state,
ast_devstate2str(device_state));
2663 ast_debug(3,
"Extension '%s@%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n",
2678 struct member *mem = obj;
2734 }
else if (c > 96) {
2742 const struct member *mem = obj;
2744 const char *chname = strchr(interface,
'/');
2750 for (i = 0; i < 5 && chname[i]; i++) {
2758 struct member *mem1 = obj1;
2759 struct member *mem2 = obj2;
2897 char *timestr, *maxstr, *minstr, *raisestr, *contentdup;
2900 int penaltychangetime, inserted = 0;
2902 if (!(rule =
ast_calloc(1,
sizeof(*rule)))) {
2908 if (!(maxstr = strchr(contentdup,
','))) {
2909 ast_log(
LOG_WARNING,
"Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
2915 if ((minstr = strchr(maxstr,
','))) {
2917 if ((raisestr = strchr(minstr,
','))) {
2924 timestr = contentdup;
2925 if ((penaltychangetime = atoi(timestr)) < 0) {
2926 ast_log(
LOG_WARNING,
"Improper time parameter specified for penaltychange rule at line %d. Ignoring.\n", linenum);
2931 rule->
time = penaltychangetime;
2935 if (*maxstr ==
'+' || *maxstr ==
'-' || *maxstr ==
'\0') {
2942 if (*minstr ==
'+' || *minstr ==
'-') {
2951 if (*raisestr ==
'+' || *raisestr ==
'-') {
2961 if (strcasecmp(rl_iter->
name, list_name)) {
2966 if (rule->
time < rule_iter->time) {
3004 char *rulecat =
NULL;
3015 const char *timestr, *maxstr, *minstr, *raisestr, *rule_name;
3016 int penaltychangetime, rule_exists = 0, inserted = 0;
3017 int max_penalty = 0, min_penalty = 0, raise_penalty = 0;
3027 if (!(strcasecmp(rl_iter->
name, rule_name))) {
3034 if (!(new_rl =
ast_calloc(1,
sizeof(*new_rl)))) {
3042 if (!(timestr) || sscanf(timestr,
"%30d", &penaltychangetime) != 1) {
3043 ast_log(
LOG_NOTICE,
"Failed to parse time (%s) for one of the %s rules, skipping it\n",
3047 if (!(new_penalty_rule =
ast_calloc(1,
sizeof(*new_penalty_rule)))) {
3052 ast_strlen_zero(maxstr) || sscanf(maxstr,
"%30d", &max_penalty) != 1) {
3056 if (*maxstr ==
'+' || *maxstr ==
'-') {
3061 ast_strlen_zero(minstr) || sscanf(minstr,
"%30d", &min_penalty) != 1) {
3065 if (*minstr ==
'+' || *minstr ==
'-') {
3070 ast_strlen_zero(raisestr) || sscanf(raisestr,
"%30d", &raise_penalty) != 1) {
3074 if (*raisestr ==
'+' || *raisestr ==
'-') {
3078 new_penalty_rule->
time = penaltychangetime;
3080 new_penalty_rule->
max_value = max_penalty;
3082 new_penalty_rule->
min_value = min_penalty;
3086 if (new_penalty_rule->
time < pr_iter->
time) {
3104 char *option =
NULL;
3105 while ((option =
strsep(&value_copy,
","))) {
3106 if (!strcasecmp(option,
"paused")) {
3108 }
else if (!strcasecmp(option,
"penalty")) {
3110 }
else if (!strcasecmp(option,
"inuse")) {
3112 }
else if (!strcasecmp(option,
"ringing")) {
3114 }
else if (!strcasecmp(option,
"invalid")) {
3116 }
else if (!strcasecmp(option,
"wrapup")) {
3118 }
else if (!strcasecmp(option,
"unavailable")) {
3120 }
else if (!strcasecmp(option,
"unknown")) {
3122 }
else if (!strcasecmp(option,
"loose")) {
3124 }
else if (!strcasecmp(option,
"strict")) {
3126 }
else if ((
ast_false(option) && joinempty) || (
ast_true(option) && !joinempty)) {
3128 }
else if ((
ast_false(option) && !joinempty) || (
ast_true(option) && joinempty)) {
3131 ast_log(
LOG_WARNING,
"Unknown option %s for '%s'\n", option, joinempty ?
"joinempty" :
"leavewhenempty");
3146 if (!strcasecmp(param,
"musicclass") ||
3147 !strcasecmp(param,
"music") || !strcasecmp(param,
"musiconhold")) {
3149 }
else if (!strcasecmp(param,
"announce")) {
3151 }
else if (!strcasecmp(param,
"context")) {
3153 }
else if (!strcasecmp(param,
"timeout")) {
3158 }
else if (!strcasecmp(param,
"ringinuse")) {
3160 }
else if (!strcasecmp(param,
"setinterfacevar")) {
3162 }
else if (!strcasecmp(param,
"setqueuevar")) {
3164 }
else if (!strcasecmp(param,
"setqueueentryvar")) {
3166 }
else if (!strcasecmp(param,
"monitor-format")) {
3168 }
else if (!strcasecmp(param,
"membermacro")) {
3170 }
else if (!strcasecmp(param,
"membergosub")) {
3172 }
else if (!strcasecmp(param,
"queue-youarenext")) {
3174 }
else if (!strcasecmp(param,
"queue-thereare")) {
3176 }
else if (!strcasecmp(param,
"queue-callswaiting")) {
3178 }
else if (!strcasecmp(param,
"queue-quantity1")) {
3180 }
else if (!strcasecmp(param,
"queue-quantity2")) {
3182 }
else if (!strcasecmp(param,
"queue-holdtime")) {
3184 }
else if (!strcasecmp(param,
"queue-minutes")) {
3186 }
else if (!strcasecmp(param,
"queue-minute")) {
3188 }
else if (!strcasecmp(param,
"queue-seconds")) {
3190 }
else if (!strcasecmp(param,
"queue-thankyou")) {
3192 }
else if (!strcasecmp(param,
"queue-callerannounce")) {
3194 }
else if (!strcasecmp(param,
"queue-reporthold")) {
3196 }
else if (!strcasecmp(param,
"announce-frequency")) {
3198 }
else if (!strcasecmp(param,
"announce-to-first-user")) {
3200 }
else if (!strcasecmp(param,
"min-announce-frequency")) {
3202 ast_debug(1,
"%s=%s for queue '%s'\n", param, val, q->
name);
3203 }
else if (!strcasecmp(param,
"announce-round-seconds")) {
3210 "using 0 instead for queue '%s' at line %d of queues.conf\n",
3211 val, param, q->
name, linenum);
3214 "using 0 instead for queue '%s'\n", val, param, q->
name);
3218 }
else if (!strcasecmp(param,
"announce-holdtime")) {
3219 if (!strcasecmp(val,
"once")) {
3226 }
else if (!strcasecmp(param,
"announce-position")) {
3227 if (!strcasecmp(val,
"limit")) {
3229 }
else if (!strcasecmp(val,
"more")) {
3236 }
else if (!strcasecmp(param,
"announce-position-only-up")) {
3238 }
else if (!strcasecmp(param,
"announce-position-limit")) {
3240 }
else if (!strcasecmp(param,
"periodic-announce")) {
3241 if (strchr(val,
',')) {
3245 while ((s =
strsep(&buf,
",|"))) {
3260 }
else if (!strcasecmp(param,
"periodic-announce-frequency")) {
3262 }
else if (!strcasecmp(param,
"relative-periodic-announce")) {
3264 }
else if (!strcasecmp(param,
"random-periodic-announce")) {
3266 }
else if (!strcasecmp(param,
"retry")) {
3267 q->
retry = atoi(val);
3268 if (q->
retry <= 0) {
3271 }
else if (!strcasecmp(param,
"wrapuptime")) {
3273 }
else if (!strcasecmp(param,
"penaltymemberslimit")) {
3277 }
else if (!strcasecmp(param,
"autofill")) {
3279 }
else if (!strcasecmp(param,
"monitor-type")) {
3280 if (!strcasecmp(val,
"mixmonitor")) {
3283 }
else if (!strcasecmp(param,
"autopause")) {
3285 }
else if (!strcasecmp(param,
"autopausedelay")) {
3287 }
else if (!strcasecmp(param,
"autopausebusy")) {
3289 }
else if (!strcasecmp(param,
"autopauseunavail")) {
3291 }
else if (!strcasecmp(param,
"maxlen")) {
3296 }
else if (!strcasecmp(param,
"servicelevel")) {
3298 }
else if (!strcasecmp(param,
"strategy")) {
3307 ast_log(
LOG_WARNING,
"'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
3315 ast_log(
LOG_WARNING,
"Changing to the linear strategy currently requires asterisk to be restarted.\n");
3319 }
else if (!strcasecmp(param,
"joinempty")) {
3321 }
else if (!strcasecmp(param,
"leavewhenempty")) {
3323 }
else if (!strcasecmp(param,
"reportholdtime")) {
3325 }
else if (!strcasecmp(param,
"memberdelay")) {
3327 }
else if (!strcasecmp(param,
"weight")) {
3329 }
else if (!strcasecmp(param,
"timeoutrestart")) {
3331 }
else if (!strcasecmp(param,
"defaultrule")) {
3333 }
else if (!strcasecmp(param,
"timeoutpriority")) {
3334 if (!strcasecmp(val,
"conf")) {
3339 }
else if (failunknown) {
3341 ast_log(
LOG_WARNING,
"Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
3342 q->
name, param, linenum);
3350 #define QUEUE_PAUSED_DEVSTATE AST_DEVICE_INUSE 3351 #define QUEUE_UNPAUSED_DEVSTATE AST_DEVICE_NOT_INUSE 3352 #define QUEUE_UNKNOWN_PAUSED_DEVSTATE AST_DEVICE_NOT_INUSE 3402 const char *config_val;
3413 S_OR(membername,
"NULL"));
3419 S_OR(membername,
"NULL"));
3424 penalty = atoi(penalty_str);
3425 if ((penalty < 0) && negative_penalty_invalid) {
3427 }
else if (penalty < 0) {
3433 paused = atoi(paused_str);
3439 if (wrapuptime_str) {
3440 wrapuptime = atoi(wrapuptime_str);
3441 if (wrapuptime < 0) {
3452 ast_log(
LOG_WARNING,
"Invalid value of '%s' field for %s in queue '%s'\n", realtime_ringinuse_field, interface, q->
name);
3486 if ((m =
create_queue_member(interface, membername, penalty, paused, state_interface, ringinuse, wrapuptime))) {
3490 if (!log_membername_as_agent) {
3566 char *category =
NULL;
3567 const char *tmp_name;
3584 }
else if (!member_config) {
3595 ast_debug(1,
"Queue %s not found in realtime.\n", queuename);
3618 for (tmpvar = queue_vars; tmpvar; tmpvar = tmpvar->
next) {
3619 if (!strcasecmp(tmpvar->
name,
"strategy")) {
3622 ast_log(
LOG_WARNING,
"'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
3637 memset(tmpbuf, 0,
sizeof(tmpbuf));
3638 for (v = queue_vars; v; v = v->
next) {
3640 if (strchr(v->
name,
'_')) {
3644 while ((tmp = strchr(tmp,
'_'))) {
3709 int prev_weight = 0;
3727 if (!member_config) {
3728 ast_debug(1,
"No queue_members defined in config extconfig.conf\n");
3733 prev_weight = q->
weight ? 1 : 0;
3743 if (!q->
weight && prev_weight) {
3746 if (q->
weight && !prev_weight) {
3777 char *category =
NULL;
3793 ast_debug(3,
"Queue %s has no realtime members defined. No need for update\n", q->
name);
3870 if ((!inserted) && (qe->
prio > cur->
prio)) {
3877 if (!inserted && (qe->
prio >= cur->
prio) && position && (position <= pos + 1)) {
3881 if (position < pos) {
3882 ast_log(
LOG_NOTICE,
"Asked to be inserted at position %d but forced into position %d due to higher priority callers\n", position, pos);
3897 if (q->
count == 1) {
3905 "Position", qe->
pos,
3947 int digitlen = strlen(qe->
digits);
3950 if (digitlen <
sizeof(qe->
digits) - 2) {
3952 qe->
digits[digitlen + 1] =
'\0';
3982 int res = 0, announceposition = 0;
3983 long avgholdmins, avgholdsecs;
4013 announceposition = 1;
4017 if (announceposition == 1) {
4054 ast_verb(3,
"Hold time for %s is %ld minute(s) %ld seconds\n", qe->
parent->
name, avgholdmins, avgholdsecs);
4066 if (avgholdmins >= 1) {
4072 if (avgholdmins == 1) {
4084 if (avgholdsecs >= 1) {
4101 ast_verb(3,
"Told %s in %s their queue position (which was %d)\n",
4141 qe->
parent->
holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
4161 queue_t_ref(q,
"Copy queue pointer from queue entry");
4165 for (current = q->
head; current; current = current->
next) {
4166 if (current == qe) {
4176 "Position", qe->
pos,
4191 snprintf(posstr,
sizeof(posstr),
"%d", qe->
pos);
4195 current->
pos = ++pos;
4213 queues_t_unlink(queues, q,
"Queue is now dead; remove it from the container");
4242 for (cur = outgoing; cur; cur = cur->
q_next) {
4243 if (cur->
chan && cur->
chan != exception) {
4257 if (outgoing->
chan && (outgoing->
chan != exception)) {
4258 if (exception || cancel_answered_elsewhere) {
4276 outgoing = outgoing->
q_next;
4408 if (wrapuptime && (time(
NULL) - memberp->
lastcall) < wrapuptime) {
4409 ast_debug(1,
"Wrapuptime not yet expired on queue %s for %s\n",
4416 ast_debug(1,
"Priority queue delaying call to %s:%s\n",
4426 mem =
ao2_find(pending_members, memberp,
4433 ast_debug(1,
"%s has another call trying, can't receive call\n",
4445 ao2_link(pending_members, memberp);
4454 ast_debug(1,
"%s actually not available, can't receive call\n",
4484 const char *macrocontext, *macroexten;
4496 if ((location = strchr(tech,
'/'))) {
4618 for (cur = outgoing; cur; cur = cur->
q_next) {
4619 if (cur->stillgoing &&
4646 for (cur = outgoing; cur; cur = cur->
q_next) {
4656 ast_debug(1,
"Nobody left to try ringing in queue\n");
4661 for (cur = outgoing; cur; cur = cur->
q_next) {
4681 ast_debug(1,
"Queue timed out while ringing members.\n");
4687 for (cur = outgoing; cur; cur = cur->
q_next) {
4767 ast_verb(3,
"Playing periodic announcement\n");
4810 int callabandonedinsl = 0;
4821 "Position", qe->
pos,
4822 "OriginalPosition", qe->
opos,
4823 "HoldTime", (
int)(time(
NULL) - qe->
start));
4828 if (callabandonedinsl) {
4843 ast_verb(3,
"Nobody picked up in %d ms\n", rnatime);
4853 "Interface", interface,
4854 "MemberName", membername,
4855 "RingTime", rnatime);
4864 time_t idletime = time(&idletime)-mem->
lastcall;
4876 ast_verb(3,
"Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n",
4879 ast_verb(3,
"Failed to pause Queue Member %s in queue %s!\n", interface, qe->
parent->
name);
4885 ast_verb(3,
"Auto-Pausing Queue Member %s in all queues since they failed to answer on queue %s.\n",
4888 ast_verb(3,
"Failed to pause Queue Member %s in all queues!\n", interface);
4923 #define AST_MAX_WATCHERS 256 4942 int numbusies = prebusies;
4951 char membername[80] =
"";
4955 struct timeval start_time_tv =
ast_tvnow();
4956 int canceled_by_caller = 0;
4962 starttime = (long) time(
NULL);
4965 int numlines, retry, pos = 1;
4970 for (retry = 0; retry < 2; retry++) {
4972 for (o = outgoing; o; o = o->
q_next) {
4977 watchers[pos++] = o->
chan;
4991 if (pos > 1 || !stillgoing ||
4997 ring_one(qe, outgoing, &numbusies);
5001 if (numlines == (numbusies + numnochan)) {
5002 ast_debug(1,
"Everyone is busy at this time\n");
5004 ast_debug(3,
"No one is answering queue '%s' (%d numlines / %d busies / %d failed channels)\n", queue, numlines, numbusies, numnochan);
5027 ast_verb(3,
"%s answered %s\n", ochan_name, inchan_name);
5046 size_t encoded_size;
5055 }
else if (o->
chan && (o->
chan == winner)) {
5079 if ((stuff = strchr(tmpchan,
'/'))) {
5083 const char *forward_context;
5091 if (!strcasecmp(tech,
"Local")) {
5100 ast_verb(3,
"Now forwarding %s to '%s/%s' (thanks to %s)\n", inchan_name, tech, stuff, ochan_name);
5105 "Forwarding failed to create channel to dial '%s/%s'\n",
5214 ast_verb(3,
"%s answered %s\n", ochan_name, inchan_name);
5235 size_t encoded_size;
5246 ast_verb(3,
"%s is busy\n", ochan_name);
5248 endtime = (long) time(
NULL);
5249 endtime -= starttime;
5258 ring_one(qe, outgoing, &numbusies);
5259 starttime = (long) time(
NULL);
5265 ast_verb(3,
"%s is circuit-busy\n", ochan_name);
5267 endtime = (long) time(
NULL);
5268 endtime -= starttime;
5276 ring_one(qe, outgoing, &numbusies);
5277 starttime = (long) time(
NULL);
5283 ast_verb(3,
"%s is ringing\n", ochan_name);
5298 ast_verb(3,
"Connected line update to %s prevented.\n", inchan_name);
5304 ast_verb(3,
"%s connected line has changed. Saving it until answer for %s\n", ochan_name, inchan_name);
5344 ast_verb(3,
"Redirecting update to %s prevented\n",
5348 ast_verb(3,
"%s redirecting info has changed, passing it to %s\n",
5349 ochan_name, inchan_name);
5365 endtime = (long) time(
NULL) - starttime;
5367 rna(endtime * 1000, qe, o->
chan, on, membername, 1);
5374 ring_one(qe, outgoing, &numbusies);
5375 starttime = (long) time(
NULL);
5394 canceled_by_caller = 1;
5399 canceled_by_caller = 1;
5405 canceled_by_caller = 1;
5408 if (canceled_by_caller) {
5500 ast_debug(1,
"There %s %d available %s.\n", avl != 1 ?
"are" :
"is", avl, avl != 1 ?
"members" :
"member");
5502 while ((idx < avl) && (ch) && (ch != qe)) {
5523 if (avl == 0 && qe->
pos == 1) {
5541 char max_penalty_str[20];
5550 if (max_penalty < 0) {
5554 snprintf(max_penalty_str,
sizeof(max_penalty_str),
"%d", max_penalty);
5557 ast_debug(3,
"Setting max penalty to %d for caller %s since %d seconds have elapsed\n",
5562 char min_penalty_str[20];
5572 if (min_penalty < 0) {
5576 if (max_penalty != INT_MAX && min_penalty > max_penalty) {
5580 snprintf(min_penalty_str,
sizeof(min_penalty_str),
"%d", min_penalty);
5583 ast_debug(3,
"Setting min penalty to %d for caller %s since %d seconds have elapsed\n",
5588 char raise_penalty_str[20];
5598 if (raise_penalty < 0) {
5602 if (max_penalty != INT_MAX && raise_penalty > max_penalty) {
5606 snprintf(raise_penalty_str,
sizeof(raise_penalty_str),
"%d", raise_penalty);
5609 ast_debug(3,
"Setting raised penalty to %d for caller %s since %d seconds have elapsed\n",
5710 int newtalktime = time(
NULL) - starttime;
5719 if (!starttime || (member->
starttime != starttime)) {
5723 if (shared_lastcall) {
5757 if (callcompletedinsl) {
5765 q->
talktime = (((oldtalktime << 2) - oldtalktime) + newtalktime) >> 2;
5787 if (qe->
raise_penalty != INT_MAX && penalty < qe->raise_penalty) {
5796 ast_debug(1,
"Disregarding penalty, %d members and %d in penaltymemberslimit.\n",
5803 tmp->
metric = penalty * 1000000 * usepenalty;
5806 if (pos < qe->linpos) {
5807 tmp->
metric = 1000 + pos;
5815 tmp->
metric += penalty * 1000000 * usepenalty;
5820 if (pos < q->rrpos) {
5821 tmp->
metric = 1000 + pos;
5823 if (pos > q->
rrpos) {
5829 tmp->
metric += penalty * 1000000 * usepenalty;
5833 tmp->
metric += penalty * 1000000 * usepenalty;
5840 tmp->
metric += penalty * 1000000 * usepenalty;
5848 tmp->
metric += penalty * 1000000 * usepenalty;
5868 const char *reason =
NULL;
5879 reason =
"transfer";
5883 blob =
ast_json_pack(
"{s: s, s: s, s: s, s: I, s: I, s: s}",
5889 "Reason", reason ?:
"");
5892 queue_agent_complete_type(), blob);
6015 queue_data->
dying = 1;
6050 queue_data->
member = mem;
6070 if (!transfer_str) {
6119 if (queue_data->
dying) {
6130 ast_debug(3,
"Detected entry of caller channel %s into bridge %s\n",
6162 if (queue_data->
dying) {
6178 exten = transfer_msg->
exten;
6179 context = transfer_msg->
context;
6183 "BLINDTRANSFER",
"%s|%s|%ld|%ld|%d",
6221 if (queue_data->
dying) {
6293 if (queue_data->
dying) {
6310 ast_log(
LOG_ERROR,
"Unable to track local channel optimization for channel %s. Expect further errors\n", local_one->
base->
name);
6315 optimization->
id =
id;
6345 if (queue_data->
dying) {
6362 ast_log(
LOG_WARNING,
"Told of a local optimization end when we had no previous begin\n");
6366 if (
id != optimization->
id) {
6367 ast_log(
LOG_WARNING,
"Local optimization end event ID does not match begin (%u != %u)\n",
6368 id, optimization->
id);
6373 ast_debug(3,
"Local optimization: Changing queue caller uniqueid from %s to %s\n",
6377 ast_debug(3,
"Local optimization: Changing queue member uniqueid from %s to %s\n",
6410 if (queue_data->
dying) {
6440 ast_debug(3,
"Detected hangup of queue %s channel %s\n", reason ==
CALLER ?
"caller" :
"member",
6444 reason ==
CALLER ?
"COMPLETECALLER" :
"COMPLETEAGENT",
"%ld|%ld|%d",
6460 const char *new_channel_id;
6466 if (queue_data->
dying) {
6472 ast_debug(1,
"Replacing caller channel %s with %s due to masquerade\n", queue_data->
caller_uniqueid, new_channel_id);
6475 ast_debug(1,
"Replacing member channel %s with %s due to masquerade\n", queue_data->
member_uniqueid, new_channel_id);
6515 time_t holdstart, time_t starttime,
int callcompletedinsl)
6572 qeb->
chan = originator;
6618 char *output,
size_t size)
6620 const char *m =
input;
6624 for (p = escaped; p < escaped + size - 1; p++, m++) {
6627 if (*(m + 1) ==
'{') {
6641 if (p == escaped + size) {
6642 escaped[size - 1] =
'\0';
6650 char escaped_filename[256];
6651 char file_with_ext[
sizeof(escaped_filename) +
sizeof(qe->
parent->
monfmt)];
6652 char mixmonargs[1512];
6653 char escaped_monitor_exec[1024];
6654 const char *monitor_options;
6655 const char *monitor_exec;
6657 escaped_monitor_exec[0] =
'\0';
6672 monitor_options =
"";
6680 snprintf(file_with_ext,
sizeof(file_with_ext),
"%s.%s", escaped_filename, qe->
parent->
monfmt);
6683 snprintf(mixmonargs,
sizeof(mixmonargs),
"b%s,%s", monitor_options, escaped_monitor_exec);
6685 snprintf(mixmonargs,
sizeof(mixmonargs),
"b%s", monitor_options);
6688 ast_debug(1,
"Arguments being passed to MixMonitor: %s,%s\n", file_with_ext, mixmonargs);
6722 static int try_calling(
struct queue_ent *qe,
struct ast_flags opts,
char **opt_args,
char *announceoverride,
const char *
url,
int *tries,
int *noption,
const char *agi,
const char *macro,
const char *gosub,
int ringing)
6729 char queuename[256]=
"";
6735 int res = 0, bridge = 0;
6738 char *announce =
NULL;
6740 time_t now = time(
NULL);
6742 char nondataquality = 1;
6743 char *agiexec =
NULL;
6744 char *macroexec =
NULL;
6745 char *gosubexec =
NULL;
6746 const char *monitorfilename;
6748 int forwardsallowed = 1;
6749 int block_connected_line = 0;
6752 int callcompletedinsl;
6755 memset(&bridge_config, 0,
sizeof(bridge_config));
6805 forwardsallowed = 0;
6808 block_connected_line = 1;
6828 ast_debug(1,
"%s is trying to call a queue member.\n",
6835 announce = announceoverride;
6878 to = (qe->
expire - now) * 1000;
6896 ring_one(qe, outgoing, &numbusies);
6955 if (!res2 && announce) {
6962 long holdtime, holdtimesecs;
6965 holdtime = labs((now - qe->
start) / 60);
6966 holdtimesecs = labs((now - qe->
start) % 60);
6973 if (holdtimesecs > 1) {
7043 ast_str_set(&interfacevar, 0,
"MEMBERINTERFACE=%s,MEMBERNAME=%s,MEMBERCALLS=%d,MEMBERLASTCALL=%ld,MEMBERPENALTY=%d,MEMBERDYNAMIC=%d,MEMBERREALTIME=%d",
7052 ast_str_set(&interfacevar, 0,
"QEHOLDTIME=%ld,QEORIGINALPOS=%d",
7074 const char *monexec;
7075 ast_debug(1,
"Starting Monitor as requested.\n");
7084 if (monitorfilename) {
7086 }
else if (qe->
chan) {
7090 snprintf(tmpid,
sizeof(tmpid),
"chan-%lx", (
unsigned long)
ast_random());
7103 ast_debug(1,
"app_queue: sendurl=%s.\n", url);
7118 ast_debug(1,
"app_queue: macro=%s.\n", macroexec);
7133 char *gosub_args =
NULL;
7134 char *gosub_argstart;
7136 ast_debug(1,
"app_queue: gosub=%s.\n", gosubexec);
7138 gosub_argstart = strchr(gosubexec,
',');
7139 if (gosub_argstart) {
7140 const char *what_is_s =
"s";
7141 *gosub_argstart = 0;
7144 what_is_s =
"~~s~~";
7146 if (
ast_asprintf(&gosub_args,
"%s,%s,1(%s)", gosubexec, what_is_s, gosub_argstart + 1) < 0) {
7149 *gosub_argstart =
',';
7151 const char *what_is_s =
"s";
7154 what_is_s =
"~~s~~";
7156 if (
ast_asprintf(&gosub_args,
"%s,%s,1", gosubexec, what_is_s) < 0) {
7164 ast_log(
LOG_ERROR,
"Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
7169 ast_debug(1,
"app_queue: agi=%s.\n", agi);
7175 ast_log(
LOG_WARNING,
"Asked to execute an AGI on this channel, but could not find application (agi)!\n");
7181 (
long)(orig - to > 0 ? (orig - to) / 1000 : 0));
7188 "RingTime", (
ast_json_int_t)(orig - to > 0 ? (orig - to) / 1000 : 0));
7194 if ((queue_end_bridge =
ao2_alloc(
sizeof(*queue_end_bridge),
NULL))) {
7195 queue_end_bridge->
q = qe->
parent;
7220 res = bridge ? bridge : 1;
7252 if (!strcasecmp(interface, mem->
interface)) {
7271 struct member *cur_member;
7329 struct member *mem, tmpmem;
7343 queue_t_unref(q,
"Interface wasn't dynamic, expiring temporary reference");
7351 if (queue_persistent_members) {
7380 struct member *new_member, *old_member;
7393 if (reason_paused) {
7444 for (qe = q->
head; qe; qe = qe->
next) {
7446 ast_debug(1,
"%s Caller new prioriry %d in queue %s\n",
7447 caller, priority, queuename);
7485 if (mem->
paused == paused) {
7486 ast_debug(1,
"%spausing already-%spaused queue member %s:%s\n",
7487 (paused ?
"" :
"un"), (paused ?
"" :
"un"), q->
name, mem->
interface);
7510 if (queue_persistent_members) {
7516 "Queue:%s_avail", q->
name);
7519 "Queue:%s_avail", q->
name);
7523 "%s",
S_OR(reason,
""));
7528 static int set_member_paused(
const char *queuename,
const char *interface,
const char *reason,
int paused)
7553 (paused ?
"PAUSEALL" :
"UNPAUSEALL"),
"%s",
S_OR(reason,
""));
7587 int foundinterface = 0;
7595 sprintf(rtpenalty,
"%i", penalty);
7607 return foundinterface;
7626 ringinuse ?
"1" :
"0");
7638 int foundinterface = 0;
7648 return foundinterface;
7676 int foundinterface = 0, foundqueue = 0;
7684 if (value < 0 && !negative_penalty_invalid) {
7694 char *category =
NULL;
7726 if (foundinterface) {
7728 }
else if (!foundqueue) {
7742 int foundqueue = 0, penalty;
7774 const char *queue_name;
7783 char *wrapuptime_tok;
7793 for (entry = db_tree; entry; entry = entry->
next) {
7795 queue_name = entry->
key + strlen(pm_family) + 2;
7811 ast_log(
LOG_WARNING,
"Error loading persistent queue: '%s': it does not exist\n", queue_name);
7821 cur_ptr = queue_data;
7822 while ((member =
strsep(&cur_ptr,
",|"))) {
7827 interface =
strsep(&member,
";");
7828 penalty_tok =
strsep(&member,
";");
7829 paused_tok =
strsep(&member,
";");
7830 membername =
strsep(&member,
";");
7831 state_interface =
strsep(&member,
";");
7832 reason_paused =
strsep(&member,
";");
7833 wrapuptime_tok =
strsep(&member,
";");
7836 ast_log(
LOG_WARNING,
"Error parsing persistent member string for '%s' (penalty)\n", queue_name);
7839 penalty = strtol(penalty_tok,
NULL, 10);
7840 if (
errno == ERANGE) {
7846 ast_log(
LOG_WARNING,
"Error parsing persistent member string for '%s' (paused)\n", queue_name);
7849 paused = strtol(paused_tok,
NULL, 10);
7850 if ((
errno == ERANGE) || paused < 0 || paused > 1) {
7856 wrapuptime = strtol(wrapuptime_tok,
NULL, 10);
7857 if (
errno == ERANGE) {
7858 ast_log(
LOG_WARNING,
"Error converting wrapuptime: %s: Out of range.\n", wrapuptime_tok);
7863 ast_debug(1,
"Reload Members: Queue: %s Member: %s Name: %s Penalty: %d Paused: %d ReasonPause: %s Wrapuptime: %d\n",
7864 queue_name, interface, membername, penalty, paused, reason_paused, wrapuptime);
7866 if (
add_to_queue(queue_name, interface, membername, penalty, paused, 0, state_interface, reason_paused, wrapuptime) ==
RES_OUTOFMEMORY) {
7867 ast_log(
LOG_ERROR,
"Out of Memory when reloading persistent queue member\n");
7893 ast_log(
LOG_WARNING,
"PauseQueueMember requires an argument ([queuename],interface[,options][,reason])\n");
7902 ast_log(
LOG_WARNING,
"Missing interface argument to PauseQueueMember ([queuename],interface[,options[,reason]])\n");
7929 ast_log(
LOG_WARNING,
"UnpauseQueueMember requires an argument ([queuename],interface[,options[,reason]])\n");
7938 ast_log(
LOG_WARNING,
"Missing interface argument to PauseQueueMember ([queuename],interface[,options[,reason]])\n");
7967 ast_log(
LOG_WARNING,
"RemoveQueueMember requires an argument (queuename[,interface])\n");
7977 temppos = strrchr(
args.interface,
'-');
7985 if (log_membername_as_agent) {
8001 ast_debug(1,
"Unable to remove interface '%s' from queue '%s': Not there\n",
args.interface,
args.queuename);
8011 ast_log(
LOG_WARNING,
"Unable to remove interface from queue '%s': '%s' is not a dynamic member\n",
args.queuename,
args.interface);
8042 ast_log(
LOG_WARNING,
"AddQueueMember requires an argument (queuename[,interface[,penalty[,options[,membername[,stateinterface][,wrapuptime]]]]])\n");
8052 temppos = strrchr(
args.interface,
'-');
8059 if ((sscanf(
args.penalty,
"%30d", &penalty) != 1) || penalty < 0) {
8066 tmp =
args.wrapuptime;
8068 wrapuptime = atoi(tmp);
8069 if (wrapuptime < 0) {
8119 ast_log(
LOG_WARNING,
"QueueLog requires arguments (queuename,uniqueid,membername,event[,additionalinfo]\n");
8129 ast_log(
LOG_WARNING,
"QueueLog requires arguments (queuename,uniqueid,membername,event[,additionalinfo])\n");
8134 "%s",
args.params ?
args.params :
"");
8147 if (!strcasecmp(rl_iter->
name, tmp)) {
8155 ast_log(
LOG_ERROR,
"Memory allocation error when copying penalty rules! Aborting!\n");
8187 const char *user_priority;
8188 const char *max_penalty_str;
8189 const char *min_penalty_str;
8190 const char *raise_penalty_str;
8193 int max_penalty, min_penalty, raise_penalty;
8199 int makeannouncement = 0;
8220 ast_log(
LOG_WARNING,
"Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule[,position]]]]]]]]]\n");
8228 if (max_forwards <= 0) {
8236 ast_debug(1,
"queue: %s, options: %s, url: %s, announce: %s, timeout: %s, agi: %s, macro: %s, gosub: %s, rule: %s, position: %s\n",
8267 if (user_priority) {
8268 if (sscanf(user_priority,
"%30d", &prio) == 1) {
8276 ast_debug(3,
"NO QUEUE_PRIO variable found. Using default.\n");
8283 if (sscanf(max_penalty_str,
"%30d", &max_penalty) == 1) {
8288 max_penalty = INT_MAX;
8291 max_penalty = INT_MAX;
8295 if (sscanf(min_penalty_str,
"%30d", &min_penalty) == 1) {
8300 min_penalty = INT_MAX;
8303 min_penalty = INT_MAX;
8307 if (sscanf(raise_penalty_str,
"%30d", &raise_penalty) == 1) {
8312 raise_penalty = INT_MAX;
8315 raise_penalty = INT_MAX;
8331 if (
args.position) {
8332 position = atoi(
args.position);
8334 ast_log(
LOG_WARNING,
"Invalid position '%s' given for call to queue '%s'. Assuming no preference for position\n",
args.position,
args.queuename);
8339 ast_debug(1,
"queue: %s, expires: %ld, priority: %d\n",
8411 if (makeannouncement) {
8419 makeannouncement = 1;
8444 res =
try_calling(&qe, opts, opt_args,
args.announceoverride,
args.url, &tries, &noption,
args.agi,
args.macro,
args.gosub, ringing);
8462 ast_verb(3,
"Exiting on time-out cycle\n");
8512 }
else if (qcontinue) {
8559 char interfacevar[256] =
"";
8577 snprintf(interfacevar,
sizeof(interfacevar),
8578 "QUEUEMAX=%d,QUEUESTRATEGY=%s,QUEUECALLS=%d,QUEUEHOLDTIME=%d,QUEUETALKTIME=%d,QUEUECOMPLETED=%d,QUEUEABANDONED=%d,QUEUESRVLEVEL=%d,QUEUESRVLEVELPERF=%2.1f",
8590 snprintf(buf, len,
"%d", res);
8610 snprintf(buf, len,
"%d", q !=
NULL? 1 : 0);
8612 queue_t_unref(q,
"Done with temporary reference in QUEUE_EXISTS()");
8623 ast_log(
LOG_ERROR,
"QUEUE_MEMBER: Missing required interface argument.\n");
8630 interface, q->
name);
8658 "Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
8667 "Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
8674 if (!strcasecmp(
args.option,
"logged")) {
8684 }
else if (!strcasecmp(
args.option,
"free")) {
8694 }
else if (!strcasecmp(
args.option,
"ready")) {
8707 }
else if (!strcasecmp(
args.option,
"count")) {
8709 }
else if (!strcasecmp(
args.option,
"penalty")) {
8715 }
else if (!strcasecmp(
args.option,
"paused")) {
8721 }
else if ((!strcasecmp(
args.option,
"ignorebusy")
8722 || !strcasecmp(
args.option,
"ringinuse"))) {
8732 queue_t_unref(q,
"Done with temporary reference in QUEUE_MEMBER()");
8737 snprintf(buf, len,
"%d", count);
8755 "Missing required argument. %s([<queuename>],<option>,<interface>)\n",
8765 "Missing required argument. %s([<queuename>],<option>,<interface>)\n",
8775 memvalue = atoi(value);
8776 if (!strcasecmp(
args.option,
"penalty")) {
8781 }
else if (!strcasecmp(
args.option,
"paused")) {
8782 memvalue = (memvalue <= 0) ? 0 : 1;
8787 }
else if (!strcasecmp(
args.option,
"ignorebusy")
8788 || !strcasecmp(
args.option,
"ringinuse")) {
8789 memvalue = (memvalue <= 0) ? 0 : 1;
8812 static int depflag = 1;
8816 ast_log(
LOG_NOTICE,
"The function QUEUE_MEMBER_COUNT has been deprecated in favor of the QUEUE_MEMBER function and will not be in further releases.\n");
8836 queue_t_unref(q,
"Done with temporary reference in QUEUE_MEMBER_COUNT");
8841 snprintf(buf, len,
"%d", count);
8862 ast_log(
LOG_ERROR,
"Missing argument. QUEUE_GET_CHANNEL(<queuename>,<position>)\n");
8877 if (sscanf(
args.position,
"%30d", &position) != 1) {
8882 ast_log (
LOG_ERROR,
"<position> parameter must be an integer greater than zero.\n");
8896 if (q->
count >= position) {
8899 for (qe = q->
head; qe; qe = qe->
next) {
8900 if (qe->
pos == position) {
8907 queue_t_unref(q,
"Done with reference in QUEUE_GET_CHANNEL()");
8937 ast_log(
LOG_ERROR,
"QUEUE_WAITING_COUNT requires an argument: queuename\n");
8945 queue_t_unref(q,
"Done with reference in QUEUE_WAITING_COUNT()");
8957 snprintf(buf, len,
"%d", count);
8977 int buflen = 0, count = 0;
8985 strncat(buf + buflen,
",", len - buflen - 1);
8988 strncat(buf + buflen, m->
interface, len - buflen - 1);
8991 if (buflen >= len - 2) {
9005 buf[len - 1] =
'\0';
9022 ast_log(
LOG_ERROR,
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
9028 if (
args.argc < 2) {
9029 ast_log(
LOG_ERROR,
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
9036 snprintf (buf, len,
"%d", penalty);
9052 ast_log(
LOG_ERROR,
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
9058 if (
args.argc < 2) {
9059 ast_log(
LOG_ERROR,
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
9063 penalty = atoi(value);
9080 .
name =
"QUEUE_EXISTS",
9085 .
name =
"QUEUE_VARIABLES",
9090 .
name =
"QUEUE_MEMBER",
9096 .
name =
"QUEUE_MEMBER_COUNT",
9101 .
name =
"QUEUE_GET_CHANNEL",
9106 .
name =
"QUEUE_WAITING_COUNT",
9111 .
name =
"QUEUE_MEMBER_LIST",
9116 .
name =
"QUEUE_MEMBER_PENALTY",
9130 const char *general_val =
NULL;
9132 realtime_rules =
ast_true(general_val);
9147 char *rulecat =
NULL;
9152 ast_log(
LOG_NOTICE,
"No queuerules.conf file found, queues will not follow penalty rules\n");
9155 ast_log(
LOG_NOTICE,
"queuerules.conf has not changed since it was last loaded. Not taking any action.\n");
9158 ast_log(
LOG_ERROR,
"Config file queuerules.conf is in an invalid format. Aborting.\n");
9170 if (!strcasecmp(rulecat,
"general")) {
9174 if (!(new_rl =
ast_calloc(1,
sizeof(*new_rl)))) {
9182 if(!strcasecmp(rulevar->
name,
"penaltychange"))
9203 queue_persistent_members = 0;
9204 autofill_default = 0;
9205 montype_default = 0;
9206 shared_lastcall = 0;
9207 negative_penalty_invalid = 0;
9208 log_membername_as_agent = 0;
9214 const char *general_val =
NULL;
9216 queue_persistent_members =
ast_true(general_val);
9219 autofill_default =
ast_true(general_val);
9222 if (!strcasecmp(general_val,
"mixmonitor"))
9223 montype_default = 1;
9226 shared_lastcall =
ast_true(general_val);
9229 negative_penalty_invalid =
ast_true(general_val);
9232 log_membername_as_agent =
ast_true(general_val);
9246 char *membername, *interface, *state_interface, *
tmp;
9248 struct member *cur, *newm;
9272 interface =
args.interface;
9276 penalty = atoi(tmp);
9285 membername =
args.membername;
9288 membername = interface;
9292 state_interface =
args.state_interface;
9295 state_interface = interface;
9299 tmp =
args.ringinuse;
9306 ast_log(
LOG_ERROR,
"Member %s has an invalid ringinuse value. Using %s ringinuse value.\n",
9307 membername, q->
name);
9315 tmp =
args.wrapuptime;
9317 wrapuptime = atoi(tmp);
9318 if (wrapuptime < 0) {
9329 if ((newm =
create_queue_member(interface, membername, penalty, cur ? cur->
paused : 0, state_interface, ringinuse, wrapuptime))) {
9364 if (!member->
delme) {
9395 int prev_weight = 0;
9418 prev_weight = q->
weight ? 1 : 0;
9439 ast_log(
LOG_WARNING,
"'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
9448 if (member_reload) {
9455 if (queue_reload && strcasecmp(var->
name,
"member")) {
9462 if (member_reload && !strcasecmp(var->
name,
"member")) {
9468 if (member_reload) {
9484 if (!q->
weight && prev_weight) {
9486 }
else if (q->
weight && !prev_weight) {
9491 if (member_reload) {
9509 char *queuename = arg;
9519 char *queuename = arg;
9548 ast_log(
LOG_NOTICE,
"No call queueing config file (queues.conf), so no call queues\n");
9553 ast_log(
LOG_ERROR,
"Config file queues.conf is in an invalid format. Aborting.\n");
9567 if (!strcasecmp(cat,
"general") && queue_reload) {
9660 time_t now = time(
NULL);
9677 ast_str_append(&out, 0,
") in '%s' strategy (%ds holdtime, %ds talktime), W:%d, C:%d, A:%d, SL:%2.1f%%, SL2:%2.1f%% within %ds",
9723 ast_str_append(&out, 0,
" has taken %d calls (last was %ld secs ago)",
9740 for (qe = q->
head; qe; qe = qe->
next) {
9741 ast_str_set(&out, 0,
" %d. %s (wait: %ld:%2.2ld, prio: %d)",
9743 (
long) (now - qe->
start) % 60, qe->
prio);
9767 if (argc != 2 && argc != 3) {
9778 ast_str_set(&out, 0,
"No such queue: %s.", argv[2]);
9790 char *category =
NULL;
9810 if (!sorted_queues) {
9834 if (!realtime_queue) {
9839 queue_t_unref(realtime_queue,
"Queue is already in memory");
9871 int list_len, word_len = strlen(word);
9872 const char *find, *end_find, *end_list;
9875 while(isspace(*list)) {
9879 while((find = strstr(list, word))) {
9881 if (find != list && *(find - 1) !=
' ') {
9884 while(!isspace(*list) && *list !=
'\0') {
9888 while(isspace(*list)) {
9895 list_len = strlen(list);
9896 end_find = find + word_len;
9897 end_list = list + list_len;
9898 if (end_find == end_list || *end_find !=
' ') {
9901 while(!isspace(*list) && *list !=
'\0') {
9905 while(isspace(*list)) {
9934 int wordlen = strlen(word);
9936 const char *word_list =
NULL;
9940 if (word_list_offset && strlen(line) >= word_list_offset) {
9941 word_list = line + word_list_offset;
9946 if (!strncasecmp(word, q->
name, wordlen) && ++which > state
9959 if (!ret && which == state && !wordlen && !strncmp(
"queue show", line, 10)) {
9980 "Usage: queue show\n" 9981 " Provides summary information on a specified queue.\n";
10031 int qchancount = 0;
10032 int qlongestholdtime = 0;
10033 int qsummaries = 0;
10047 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
10059 qlongestholdtime = 0;
10073 for (qe = q->
head; qe; qe = qe->
next) {
10074 if ((now - qe->
start) > qlongestholdtime) {
10075 qlongestholdtime = now - qe->
start;
10082 "Available: %d\r\n" 10086 "LongestHoldTime: %d\r\n" 10089 q->
name, qmemcount, qmemavail, qchancount, q->
holdtime, q->
talktime, qlongestholdtime, idText);
10125 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
10144 "Completed: %d\r\n" 10145 "Abandoned: %d\r\n" 10146 "ServiceLevel: %d\r\n" 10147 "ServicelevelPerf: %2.1f\r\n" 10148 "ServicelevelPerf2: %2.1f\r\n" 10164 "StateInterface: %s\r\n" 10165 "Membership: %s\r\n" 10167 "CallsTaken: %d\r\n" 10169 "LastPause: %d\r\n" 10173 "PausedReason: %s\r\n" 10174 "Wrapuptime: %d\r\n" 10188 for (qe = q->
head; qe; qe = qe->
next) {
10194 "CallerIDNum: %s\r\n" 10195 "CallerIDName: %s\r\n" 10196 "ConnectedLineNum: %s\r\n" 10197 "ConnectedLineName: %s\r\n" 10207 (
long) (now - qe->
start), qe->
prio, idText);
10224 const char *queuename, *interface, *penalty_s, *paused_s, *membername, *state_interface, *wrapuptime_s;
10225 int paused, penalty, wrapuptime = 0;
10247 }
else if (sscanf(penalty_s,
"%30d", &penalty) != 1 || penalty < 0) {
10253 }
else if (sscanf(wrapuptime_s,
"%30d", &wrapuptime) != 1 || wrapuptime < 0) {
10263 switch (
add_to_queue(queuename, interface, membername, penalty, paused, queue_persistent_members, state_interface,
NULL, wrapuptime)) {
10266 ast_queue_log(queuename,
"MANAGER", interface,
"ADDMEMBER",
"%s", paused ?
"PAUSED" :
"");
10268 ast_queue_log(queuename,
"MANAGER", membername,
"ADDMEMBER",
"%s", paused ?
"PAUSED" :
"");
10288 const char *queuename, *interface;
10299 if (log_membername_as_agent) {
10306 ast_queue_log(queuename,
"MANAGER", interface,
"REMOVEMEMBER",
"%s",
"");
10316 astman_send_error(s, m,
"Unable to remove interface from queue: No such queue");
10335 const char *queuename, *interface, *paused_s, *reason;
10353 astman_send_ack(s, m, paused ?
"Interface paused successfully" :
"Interface unpaused successfully");
10360 const char *queuename, *
event, *
message, *interface, *uniqueid;
10373 ast_queue_log(queuename,
S_OR(uniqueid,
"NONE"), interface, event,
"%s", message);
10382 const char *queuename =
NULL;
10383 int header_found = 0;
10399 if (!header_found) {
10413 const char *queuename =
NULL;
10439 if (0 <= state && state < 100) {
10442 sprintf(num,
"%d", state);
10459 const char *queuename, *interface, *ringinuse_s;
10478 astman_send_error(s, m,
"'RingInUse' parameter must be a truth value (yes/no, on/off, 0/1, etc)");
10493 const char *queuename, *interface, *penalty_s;
10506 penalty = atoi(penalty_s);
10519 const char *queuename, *caller, *priority_s;
10539 }
else if (sscanf(priority_s,
"%30d", &priority) != 1) {
10549 astman_send_error(s, m,
"Unable to change priority caller on queue: No such queue");
10552 astman_send_error(s, m,
"Unable to change priority caller on queue: No such caller");
10563 const char *queuename, *interface, *membername =
NULL, *state_interface =
NULL;
10568 e->
command =
"queue add member";
10570 "Usage: queue add member <dial string> to <queue> [[[penalty <penalty>] as <membername>] state_interface <interface>]\n" 10571 " Add a dial string (Such as a channel,e.g. SIP/6001) to a queue with optionally: a penalty, membername and a state_interface\n";
10577 if ((a->
argc != 6) && (a->
argc != 8) && (a->
argc != 10) && (a->
argc != 12)) {
10579 }
else if (strcmp(a->
argv[4],
"to")) {
10581 }
else if ((a->
argc >= 8) && strcmp(a->
argv[6],
"penalty")) {
10583 }
else if ((a->
argc >= 10) && strcmp(a->
argv[8],
"as")) {
10585 }
else if ((a->
argc == 12) && strcmp(a->
argv[10],
"state_interface")) {
10589 queuename = a->
argv[5];
10590 interface = a->argv[3];
10591 if (a->
argc >= 8) {
10592 if (sscanf(a->
argv[7],
"%30d", &penalty) == 1) {
10594 ast_cli(a->
fd,
"Penalty must be >= 0\n");
10598 ast_cli(a->
fd,
"Penalty must be an integer >= 0\n");
10605 if (a->
argc >= 10) {
10606 membername = a->
argv[9];
10609 if (a->
argc >= 12) {
10610 state_interface = a->
argv[11];
10613 switch (
add_to_queue(queuename, interface, membername, penalty, 0, queue_persistent_members, state_interface,
NULL, 0)) {
10616 ast_queue_log(queuename,
"CLI", interface,
"ADDMEMBER",
"%s",
"");
10618 ast_queue_log(queuename,
"CLI", membername,
"ADDMEMBER",
"%s",
"");
10620 ast_cli(a->
fd,
"Added interface '%s' to queue '%s'\n", interface, queuename);
10623 ast_cli(a->
fd,
"Unable to add interface '%s' to queue '%s': Already there\n", interface, queuename);
10626 ast_cli(a->
fd,
"Unable to add interface to queue '%s': No such queue\n", queuename);
10632 ast_cli(a->
fd,
"Member not dynamic\n");
10646 int wordlen = strlen(word);
10649 if (pos > 5 || pos < 3) {
10666 if (!strncasecmp(word, m->
membername, wordlen) && ++which > state) {
10672 queue_t_unref(q,
"Done with iterator, returning interface name");
10689 const char *queuename, *interface;
10695 e->
command =
"queue remove member";
10697 "Usage: queue remove member <channel> from <queue>\n" 10698 " Remove a specific channel from a queue.\n";
10704 if (a->
argc != 6) {
10706 }
else if (strcmp(a->
argv[4],
"from")) {
10710 queuename = a->
argv[5];
10711 interface = a->argv[3];
10713 if (log_membername_as_agent) {
10720 ast_queue_log(queuename,
"CLI", interface,
"REMOVEMEMBER",
"%s",
"");
10724 ast_cli(a->
fd,
"Removed interface %s from queue '%s'\n", interface, queuename);
10728 ast_cli(a->
fd,
"Unable to remove interface '%s' from queue '%s': Not there\n", interface, queuename);
10731 ast_cli(a->
fd,
"Unable to remove interface from queue '%s': No such queue\n", queuename);
10737 ast_cli(a->
fd,
"Unable to remove interface '%s' from queue '%s': Member is not dynamic\n", interface, queuename);
10752 const char *queuename, *caller;
10758 e->
command =
"queue priority caller";
10760 "Usage: queue priority caller <channel> on <queue> to <priority>\n" 10761 " Change the priority of a channel on a queue.\n";
10767 if (a->
argc != 8) {
10769 }
else if (strcmp(a->
argv[4],
"on")) {
10771 }
else if (strcmp(a->
argv[6],
"to")) {
10773 }
else if (sscanf(a->
argv[7],
"%30d", &priority) != 1) {
10778 caller = a->
argv[3];
10779 queuename = a->
argv[5];
10786 ast_cli(a->
fd,
"Unable change priority caller %s on queue '%s': No such queue\n", caller, queuename);
10789 ast_cli(a->
fd,
"Unable to change priority caller '%s' on queue '%s': Not there\n", caller, queuename);
10820 const char *queuename, *interface, *reason;
10825 e->
command =
"queue {pause|unpause} member";
10827 "Usage: queue {pause|unpause} member <member> [queue <queue> [reason <reason>]]\n" 10828 " Pause or unpause a queue member. Not specifying a particular queue\n" 10829 " will pause or unpause a member across all queues to which the member\n" 10838 }
else if (a->
argc >= 5 && strcmp(a->
argv[4],
"queue")) {
10840 }
else if (a->
argc == 8 && strcmp(a->
argv[6],
"reason")) {
10845 interface = a->argv[3];
10848 paused = !strcasecmp(a->
argv[1],
"pause");
10851 ast_cli(a->
fd,
"%spaused interface '%s'", paused ?
"" :
"un", interface);
10853 ast_cli(a->
fd,
" in queue '%s'", queuename);
10856 ast_cli(a->
fd,
" for reason '%s'", reason);
10861 ast_cli(a->
fd,
"Unable to %spause interface '%s'", paused ?
"" :
"un", interface);
10863 ast_cli(a->
fd,
" in queue '%s'", queuename);
10866 ast_cli(a->
fd,
" for reason '%s'", reason);
10898 const char *queuename =
NULL, *interface;
10903 e->
command =
"queue set ringinuse";
10905 "Usage: queue set ringinuse <yes/no> on <interface> [in <queue>]\n" 10906 " Set a member's ringinuse in the queue specified. If no queue is specified\n" 10907 " then that interface's penalty is set in all queues to which that interface is a member.\n";
10915 if (a->
argc != 6 && a->
argc != 8) {
10920 if (strcmp(a->
argv[4],
"on") || (a->
argc > 6 && strcmp(a->
argv[6],
"in"))) {
10925 if (a->
argc == 8) {
10926 queuename = a->
argv[7];
10930 interface = a->argv[5];
10943 ast_cli(a->
fd,
"Set ringinuse on interface '%s' from queue '%s'\n", interface, queuename);
10946 ast_cli(a->
fd,
"Failed to set ringinuse on interface '%s' from queue '%s'\n", interface, queuename);
10955 const char *queuename =
NULL, *interface;
10960 e->
command =
"queue set penalty";
10962 "Usage: queue set penalty <penalty> on <interface> [in <queue>]\n" 10963 " Set a member's penalty in the queue specified. If no queue is specified\n" 10964 " then that interface's penalty is set in all queues to which that interface is a member\n";
10970 if (a->
argc != 6 && a->
argc != 8) {
10972 }
else if (strcmp(a->
argv[4],
"on") || (a->
argc > 6 && strcmp(a->
argv[6],
"in"))) {
10976 if (a->
argc == 8) {
10977 queuename = a->
argv[7];
10979 interface = a->argv[5];
10980 penalty = atoi(a->
argv[3]);
10984 ast_cli(a->
fd,
"Set penalty on interface '%s' from queue '%s'\n", interface, queuename);
10987 ast_cli(a->
fd,
"Failed to set penalty on interface '%s' from queue '%s'\n", interface, queuename);
10998 int wordlen = strlen(word);
11006 if (!strncasecmp(word, rl_iter->
name, wordlen) && ++which > state) {
11023 e->
command =
"queue show rules";
11025 "Usage: queue show rules [rulename]\n" 11026 " Show the list of rules associated with rulename. If no\n" 11027 " rulename is specified, list all rules defined in queuerules.conf\n";
11033 if (a->
argc != 3 && a->
argc != 4) {
11037 rule = a->
argc == 4 ? a->
argv[3] :
"";
11043 ast_cli(a->
fd,
"\tAfter %d seconds, adjust QUEUE_MAX_PENALTY %s %d, adjust QUEUE_MIN_PENALTY %s %d and adjust QUEUE_RAISE_PENALTY %s %d\n", pr_iter->
time, pr_iter->
max_relative ?
"by" :
"to", pr_iter->
max_value, pr_iter->
min_relative ?
"by" :
"to", pr_iter->
min_value, pr_iter->
raise_relative ?
"by" :
"to", pr_iter->
raise_value);
11058 e->
command =
"queue reset stats";
11060 "Usage: queue reset stats [<queuenames>]\n" 11062 "Issuing this command will reset statistics for\n" 11063 "<queuenames>, or for all queues if no queue is\n" 11078 if (a->
argc == 3) {
11083 for (i = 3; i < a->
argc; ++i) {
11097 e->
command =
"queue reload {parameters|members|rules|all}";
11099 "Usage: queue reload {parameters|members|rules|all} [<queuenames>]\n" 11100 "Reload queues. If <queuenames> are specified, only reload information pertaining\n" 11101 "to <queuenames>. One of 'parameters,' 'members,' 'rules,' or 'all' must be\n" 11102 "specified in order to know what information to reload. Below is an explanation\n" 11103 "of each of these qualifiers.\n" 11105 "\t'members' - reload queue members from queues.conf\n" 11106 "\t'parameters' - reload all queue options except for queue members\n" 11107 "\t'rules' - reload the queuerules.conf file\n" 11108 "\t'all' - reload queue rules, parameters, and members\n" 11110 "Note: the 'rules' qualifier here cannot actually be applied to a specific queue.\n" 11111 "Use of the 'rules' qualifier causes queuerules.conf to be reloaded. Even if only\n" 11112 "one queue is specified when using this command, reloading queue rules may cause\n" 11113 "other queues to be affected\n";
11118 const char *command_end = a->
line + strlen(
"queue reload ");
11119 command_end = strchr(command_end,
' ');
11120 if (!command_end) {
11121 command_end = a->
line + strlen(a->
line);
11132 if (!strcasecmp(a->
argv[2],
"rules")) {
11134 }
else if (!strcasecmp(a->
argv[2],
"members")) {
11136 }
else if (!strcasecmp(a->
argv[2],
"parameters")) {
11138 }
else if (!strcasecmp(a->
argv[2],
"all")) {
11142 if (a->
argc == 3) {
11147 for (i = 3; i < a->
argc; ++i) {
11163 int newtalktime = 0;
11174 ast_log(
LOG_WARNING,
"QueueUpdate requires arguments (queuename,uniqueid,agent,status,talktime,params[totaltime,callednumber])\n");
11183 ast_log(
LOG_WARNING,
"Missing argument to QueueUpdate (queuename,uniqueid,agent,status,talktime,params[totaltime|callednumber])\n");
11188 newtalktime = atoi(
args.talktime);
11202 if (!strcasecmp(
args.status,
"ANSWER")) {
11204 q->
talktime = (((oldtalktime << 2) - oldtalktime) + newtalktime) >> 2;
11210 if (newtalktime <= q->servicelevel) {
11253 agent_router =
NULL;
11340 if (!pending_members) {
11359 if (!member_config) {
11360 realtime_ringinuse_field =
"ringinuse";
11362 const char *config_val;
11365 ast_log(
LOG_NOTICE,
"ringinuse field entries found in queue_members table. Using 'ringinuse'\n");
11366 realtime_ringinuse_field =
"ringinuse";
11368 ast_log(
LOG_NOTICE,
"ignorebusy field found in queue_members table with no ringinuse field. Using 'ignorebusy'\n");
11369 realtime_ringinuse_field =
"ignorebusy";
11371 ast_log(
LOG_NOTICE,
"No entries were found for ringinuse/ignorebusy in queue_members table. Using 'ringinuse'\n");
11372 realtime_ringinuse_field =
"ringinuse";
11377 if (queue_persistent_members) {
11412 if (!device_state_sub) {
11420 if (!manager_topic || !queue_topic) {
11425 if (!topic_forwarder) {
11436 if (!agent_router) {
11504 .optional_modules =
"res_monitor",
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static int get_member_penalty(char *queuename, char *interface)
struct ast_str * sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS]
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
static int queue_function_qac_dep(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Get the total number of members in a specific queue (Deprecated)
struct ast_variable * next
struct stasis_message_type * ast_blind_transfer_type(void)
Message type for ast_blind_transfer_message.
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
static struct ast_manager_event_blob * queue_member_added_to_ami(struct stasis_message *message)
struct callattempt * q_next
Struct containing info for an AMI event to send out.
enum sip_cc_notify_state state
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
static void queue_stasis_data_destructor(void *obj)
static void do_print(struct mansession *s, int fd, const char *str)
direct ouput to manager or cli with proper terminator
static int say_position(struct queue_ent *qe, int ringing)
const char * ast_devstate2str(enum ast_device_state devstate) attribute_pure
Convert device state to text string for output.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
struct call_queue * parent
#define ast_channel_lock(chan)
void ast_channel_req_accountcodes_precious(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
struct ast_party_dialed::@246 number
Dialed/Called number.
Local proxy channel special access.
static struct ast_custom_function queuewaitingcount_function
static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
static int change_priority_caller_on_queue(const char *queuename, const char *caller, int priority)
Change priority caller into a queue.
#define AST_CLI_DEFINE(fn, txt,...)
ast_device_state
Device States.
static int member_hash_fn(const void *obj, const int flags)
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
char * str
Subscriber phone number (Malloced)
static struct member * create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface, int ringinuse, int wrapuptime)
allocate space for new queue member and set fields based on parameters passed
static void queue_publish_multi_channel_snapshot_blob(struct stasis_topic *topic, struct ast_channel_snapshot *caller_snapshot, struct ast_channel_snapshot *agent_snapshot, struct stasis_message_type *type, struct ast_json *blob)
static int qupd_exec(struct ast_channel *chan, const char *data)
Update Queue with data of an outgoing call.
static void handle_blind_transfer(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
Handle a blind transfer event.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
#define MAX_PERIODIC_ANNOUNCEMENTS
#define AST_LIST_LOCK(head)
Locks a list.
static int store_next_rr(struct queue_ent *qe, struct callattempt *outgoing)
Search for best metric and add to Round Robbin queue.
struct ast_channel_snapshot_base * base
Asterisk locking-related definitions:
union ast_attended_transfer_message::@324 dest
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
static int manager_queue_member_ringinuse(struct mansession *s, const struct message *m)
static struct ast_manager_event_blob * queue_member_status_to_ami(struct stasis_message *message)
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel's connected line information.
#define stasis_message_router_create_pool(topic)
static int rqm_exec(struct ast_channel *chan, const char *data)
RemoveQueueMember application.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
char digits[AST_MAX_EXTENSION]
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
char * str
Subscriber phone number (Malloced)
const ast_string_field sound_holdtime
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
static struct call_queue * find_load_queue_rt_friendly(const char *queuename)
struct ast_channel * chan
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
static const struct @66 queue_results[]
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
static int mark_member_dead(void *obj, void *arg, int flags)
const ast_string_field membergosub
struct ast_flags features_callee
String manipulation functions.
static char * handle_queue_add_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for channel enter bridge blob messages.
static int load_module(void)
Load the module.
static char * handle_queue_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int set_member_ringinuse_help_members(struct call_queue *q, const char *interface, int ringinuse)
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
Message representing attended transfer.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
static struct ast_manager_event_blob * queue_member_penalty_to_ami(struct stasis_message *message)
struct stasis_message_router * bridge_router
struct ast_channel_snapshot * channel
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
static struct ao2_container * pending_members
struct ast_party_id id
Connected party ID.
int last_periodic_announce_sound
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
static void handle_hangup(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static struct ast_custom_function queuegetchannel_function
The arg parameter is a search key, but is not an object.
static struct ast_manager_event_blob * queue_multi_channel_to_ami(const char *type, struct stasis_message *message)
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
#define ast_test_flag(p, flag)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
char exten[AST_MAX_EXTENSION]
unsigned int autopauseunavail
Support for translation of data formats. translate.c.
static int upqm_exec(struct ast_channel *chan, const char *data)
UnPauseQueueMember application.
Message published during a blind transfer.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_party_name name
Subscriber name.
void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message using the latest snapshot from the cache.
#define ANNOUNCEPOSITION_NO
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
int ast_extension_state_del(int id, ast_state_cb_type change_cb)
Deletes a state change watcher by ID.
static void queue_bridge_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static char * complete_queue_pause_member(const char *line, const char *word, int pos, int state)
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static struct ast_manager_event_blob * queue_member_removed_to_ami(struct stasis_message *message)
char state_interface[AST_CHANNEL_NAME]
static const struct strategy strategies[]
static struct ast_manager_event_blob * queue_caller_abandon_to_ami(struct stasis_message *message)
static void update_realtime_members(struct call_queue *q)
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
static char * handle_queue_remove_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
#define DEFAULT_MIN_ANNOUNCE_FREQUENCY
The minimum number of seconds between position announcements.
unsigned int announceposition_only_up
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
struct ast_channel_snapshot * snapshot
static void queue_rules_set_global_params(struct ast_config *cfg)
static int manager_queue_reset(struct mansession *s, const struct message *m)
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
#define ast_set_flag(p, flag)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static struct ast_manager_event_blob * queue_caller_leave_to_ami(struct stasis_message *message)
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
static struct ast_manager_event_blob * queue_agent_complete_to_ami(struct stasis_message *message)
descriptor for a cli entry.
static int manager_queue_member_penalty(struct mansession *s, const struct message *m)
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
static void member_remove_from_queue(struct call_queue *queue, struct member *mem)
static int negative_penalty_invalid
queues.conf [general] option
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
#define ao2_callback(c, flags, cb_fn, arg)
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
#define CONFIG_STATUS_FILEINVALID
static int kill_dead_members(void *obj, void *arg, int flags)
enum ast_device_state state
static struct ast_manager_event_blob * queue_caller_join_to_ami(struct stasis_message *message)
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
#define MAX_QUEUE_BUCKETS
enum ast_state_cb_update_reason reason
unsigned int timeoutrestart
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed...
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Structure for variables, used for configurations and for channel variables.
struct stasis_topic * ast_queue_topic_all(void)
Get the Stasis Message Bus API topic for queue messages.
static void queue_reset_global_params(void)
Structure representing a snapshot of channel state.
void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt,...)
static struct ast_custom_function queuemembercount_dep
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
static int log_membername_as_agent
queues.conf [general] option
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
static int queue_function_exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Check if a given queue exists.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
Calculate the metric of each member in the outgoing callattempts.
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Assume that the ao2_container is already locked.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
unsigned int announceholdtime
ast_channel_state
ast_channel states
static int reload_queue_rules(int reload)
Reload the rules defined in queuerules.conf.
char * str
Subscriber name (Malloced)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
static int mark_unfound(void *obj, void *arg, int flags)
int ast_db_get_allocated(const char *family, const char *key, char **out)
Get key value specified by family/key as a heap allocated string.
const ast_string_field uniqueid
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static char * __queues_show(struct mansession *s, int fd, int argc, const char *const *argv)
Show queue(s) status and statistics.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
#define queue_t_ref(q, tag)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
struct rule_list::@71 rules
static void reload_single_member(const char *memberdata, struct call_queue *q)
reload information pertaining to a single member
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
static char * handle_queue_change_priority_caller(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
unsigned int setinterfacevar
int ast_start_mixmonitor(struct ast_channel *chan, const char *filename, const char *options)
Start a mixmonitor on a channel with the given parameters.
#define ast_str_alloca(init_len)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
static int setup_stasis_subs(struct queue_ent *qe, struct ast_channel *peer, struct member *mem, time_t holdstart, time_t starttime, int callcompletedinsl)
#define ast_strdup(str)
A wrapper for strdup()
static int call(void *data)
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
static void set_queue_result(struct ast_channel *chan, enum queue_result res)
sets the QUEUESTATUS channel variable
static int queue_function_memberpenalty_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Dialplan function QUEUE_MEMBER_PENALTY() Gets the members penalty.
char bridge[AST_UUID_STR_LEN]
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
static int queue_delme_members_decrement_followers(void *obj, void *arg, int flag)
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
struct ast_aoc_decoded * aoc_s_rate_list
static const struct ast_app_option queue_exec_options[128]
static int say_periodic_announcement(struct queue_ent *qe, int ringing)
Playback announcement to queued members if period has elapsed.
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
const ast_string_field sound_thanks
static void clear_queue(struct call_queue *q)
void ast_cli(int fd, const char *fmt,...)
static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
static int input(yyscan_t yyscanner)
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
static char * queue_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void handle_masquerade(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
int ast_unregister_application(const char *app)
Unregister an application.
unsigned int announce_to_first_user
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
struct ao2_container * members
const char * ast_channel_call_forward(const struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
static void pending_members_remove(struct member *mem)
#define ast_verb(level,...)
struct ast_bridge_channel_snapshot_pair to_transferee
static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
const ast_string_field membermacro
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
int announcepositionlimit
static int queue_function_mem_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Dialplan function QUEUE_MEMBER() Sets the members penalty / paused / ringinuse.
static int insert_penaltychange(const char *list_name, const char *content, const int linenum)
Change queue penalty by adding rule.
static struct ast_custom_function queueexists_function
static void rt_handle_member_record(struct call_queue *q, char *category, struct ast_config *member_config)
Find rt member record to update otherwise create one.
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate...
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
char interface[AST_CHANNEL_NAME]
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
struct ast_json * ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *obj)
Retrieve the JSON blob from a ast_multi_channel_blob. Returned ast_json is still owned by obj...
static struct stasis_forward * topic_forwarder
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
static int strat2int(const char *strategy)
static int extension_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Blob of data associated with a channel.
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
#define ast_strlen_zero(foo)
static int member_status_available(int status)
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
const char * source_chan_uniqueid
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
static int manager_queue_rule_show(struct mansession *s, const struct message *m)
struct ast_str * ast_manager_str_from_json_object(struct ast_json *blob, key_exclusion_cb exclusion_cb)
Convert a JSON object into an AMI compatible string.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
static char * handle_queue_set_member_ringinuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
const struct ast_channel_tech * tech
static int wait_a_bit(struct queue_ent *qe)
static struct ast_manager_event_blob * queue_channel_to_ami(const char *type, struct stasis_message *message)
static struct callattempt * wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
Wait for a member to answer the call.
static int compare_weight(struct call_queue *rq, struct member *member)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ast_party_id id
Caller party ID.
static int queue_function_var(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
create interface var with all queue details.
static int queue_function_memberpenalty_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Dialplan function QUEUE_MEMBER_PENALTY() Sets the members penalty.
struct ast_bridge_channel_snapshot_pair to_transfer_target
Configuration File Parser.
enum ast_extension_states exten_state
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
struct ast_bridge_snapshot * bridge
static char * realtime_ringinuse_field
name of the ringinuse field in the realtime database
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
#define ast_debug(level,...)
Log a DEBUG message.
enum ast_transfer_result result
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
const char * predial_callee
static void member_add_to_queue(struct call_queue *queue, struct member *mem)
struct ast_db_entry * next
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Generic Advice of Charge encode and decode routines.
#define ast_config_load(filename, flags)
Load a config file.
const ast_string_field sound_minute
struct ast_party_connected_line connected
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
Configure a queue parameter.
static struct ast_manager_event_blob * queue_member_pause_to_ami(struct stasis_message *message)
static struct ast_custom_function queuemembercount_function
struct ast_party_id ani
Automatic Number Identification (ANI)
int periodicannouncefrequency
static struct ao2_container * queues
static void end_bridge_callback(void *data)
General Asterisk PBX channel definitions.
struct call_queue * queue
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
struct ast_channel_snapshot * links[2]
static struct ast_custom_function queuememberpenalty_function
static int pqm_exec(struct ast_channel *chan, const char *data)
PauseQueueMember application.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static char * complete_queue_set_member_value(const char *line, const char *word, int pos, int state)
const struct ast_eid * eid
The EID of the server where this message originated.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
static char * complete_queue(const char *line, const char *word, int pos, int state, ptrdiff_t word_list_offset)
Check if a given word is in a space-delimited list.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
#define QUEUE_PAUSED_DEVSTATE
static void handle_bridge_enter(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
unsigned int block_connected_update
static void parse_empty_options(const char *value, enum empty_conditions *empty, int joinempty)
const ast_string_field sound_thereare
#define MAX_CALL_ATTEMPT_BUCKETS
Data structure associated with a custom dialplan function.
#define AST_CAUSE_ANSWERED_ELSEWHERE
void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
static void free_members(struct call_queue *q, int all)
Iterate through queue's member list and delete them.
static struct member * interface_exists(struct call_queue *q, const char *interface)
static void ringing(struct ast_channel *chan)
Helper method to send a ringing indication to a channel in a bridge.
#define AST_MAX_EXTENSION
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
const ast_string_field context
static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl, time_t starttime)
update the queue status
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel's redirecting information.
int AST_OPTIONAL_API_NAME() ast_monitor_start(struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action, const char *beep_id)
Start monitoring a channel.
Structure representing relevant data during a local channel optimization.
static struct stasis_message_router * agent_router
#define AST_STRING_FIELD(name)
Declare a string field.
static struct member * find_member_by_queuename_and_interface(const char *queuename, const char *interface)
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
void * end_bridge_callback_data
Caller Party information.
structure to hold extensions
#define ao2_ref(o, delta)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
unsigned int autopausebusy
void ast_config_destroy(struct ast_config *config)
Destroys a config.
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
static struct ast_manager_event_blob * queue_member_ringinuse_to_ami(struct stasis_message *message)
In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
static int reload_handler(int reload, struct ast_flags *mask, const char *queuename)
The command center for all reload operations.
long int ast_random(void)
const ast_string_field sound_next
#define ast_strdupa(s)
duplicate a string in memory from the stack
static struct callattempt * find_best(struct callattempt *outgoing)
find the entry with the best metric, or NULL
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
A set of macros to manage forward-linked lists.
#define ast_malloc(len)
A wrapper for malloc()
struct stasis_message_type * ast_channel_agent_login_type(void)
Message type for agent login on a channel.
struct ast_bridge_snapshot * bridge
static void queue_set_global_params(struct ast_config *cfg)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct call_queue * lastqueue
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
struct stasis_message_type * ast_channel_agent_logoff_type(void)
Message type for agent logoff on a channel.
static int unload_module(void)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
struct ast_party_id ani
Automatic Number Identification (ANI)
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
Blob of data associated with a bridge.
static void destroy_queue_member_cb(void *obj)
#define ANNOUNCEPOSITION_MORE_THAN
static void rna(int rnatime, struct queue_ent *qe, struct ast_channel *peer, char *interface, char *membername, int autopause)
RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer...
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
const ast_string_field member_uniqueid
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
const char * ast_channel_exten(const struct ast_channel *chan)
static void escape_and_substitute(struct ast_channel *chan, const char *input, char *output, size_t size)
Core PBX routines and definitions.
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
#define stasis_message_router_create(topic)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
static int queue_member_decrement_followers(void *obj, void *arg, int flag)
struct ast_flags features_caller
#define CONFIG_STATUS_FILEUNCHANGED
#define stasis_subscribe(topic, callback, data)
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
int ast_bridge_call_with_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
Bridge a call, and add additional flags to the bridge.
static void log_attended_transfer(struct queue_stasis_data *queue_data, struct ast_attended_transfer_message *atxfer_msg)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_channel_snapshot_caller * caller
enum ast_attended_transfer_dest_type dest_type
static int num_available_members(struct call_queue *q)
Get the number of members available to accept a call.
static void handle_attended_transfer(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
Handle an attended transfer event.
static char * handle_queue_rule_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
static int montype_default
queues.conf [general] option
int ast_channel_has_role(struct ast_channel *channel, const char *role_name)
Check if a role exists on a channel.
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
static void leave_queue(struct queue_ent *qe)
Caller leaving queue.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
Part 2 of ring_one.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
We define a custom "local user" structure because we use it not only for keeping track of what is in ...
static int member_cmp_fn(void *obj1, void *obj2, int flags)
static char * complete_queue_rule_show(const char *line, const char *word, int pos, int state)
static void destroy_queue(void *obj)
Free queue's member list then its string fields.
static int pending_members_hash(const void *obj, const int flags)
int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
Parse connected line indication frame data.
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
static int queue_cmp_cb(void *obj, void *arg, int flags)
static struct ast_json * queue_member_blob_create(struct call_queue *q, struct member *mem)
static int autofill_default
queues.conf [general] option
const ast_string_field bridge_uniqueid
static void handle_local_optimization_end(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
struct stasis_message_router * channel_router
static int get_wrapuptime(struct call_queue *q, struct member *member)
Return wrapuptime.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
static int manager_queue_log_custom(struct mansession *s, const struct message *m)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
static int manager_queue_reload(struct mansession *s, const struct message *m)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason, int position)
#define QUEUE_UNPAUSED_DEVSTATE
#define ANNOUNCEPOSITION_YES
static int word_in_list(const char *list, const char *word)
Check if a given word is in a space-delimited list.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
static void queue_channel_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
#define ao2_unlink(container, obj)
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
#define ao2_t_iterator_next(iter, tag)
static void publish_dial_end_event(struct ast_channel *in, struct callattempt *outgoing, struct ast_channel *exception, const char *status)
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define QUEUE_UNKNOWN_PAUSED_DEVSTATE
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
static struct ast_custom_function queuememberlist_function
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel's connected line information...
const ast_string_field name
Channel datastore data for max forwards.
void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
Set the connected line information based on another connected line source.
static void setup_peer_after_bridge_goto(struct ast_channel *chan, struct ast_channel *peer, struct ast_flags *opts, char *opt_args[])
unsigned int reportholdtime
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_channel * chan
static int extensionstate2devicestate(int state)
Helper function which converts from extension state to device state values.
static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Get number either busy / free / ready or total members of a specific queue.
Connected Line/Party information.
unsigned int pending_connected_update
int pbx_builtin_setvar_multiple(struct ast_channel *chan, const char *data)
Parse and set multiple channel variables, where the pairs are separated by the ',' character...
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
const ast_string_field caller_uniqueid
char context[AST_MAX_CONTEXT]
struct local_optimization caller_optimize
#define ao2_iterator_next(iter)
#define ao2_alloc(data_size, destructor_fn)
static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused)
struct call_queue::@69 list
#define AST_TRANSFERER_ROLE_NAME
static int ql_exec(struct ast_channel *chan, const char *data)
QueueLog application.
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
static void update_status(struct call_queue *q, struct member *m, const int status)
set a member's status based on device state of that member's state_interface.
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
static void set_queue_member_ringinuse(struct call_queue *q, struct member *mem, int ringinuse)
struct stasis_message_type * ast_attended_transfer_type(void)
Message type for ast_attended_transfer_message.
static void dump_queue_members(struct call_queue *pm_queue)
Dump all members in a specific queue to the database.
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
static struct ast_manager_event_blob * queue_agent_dump_to_ami(struct stasis_message *message)
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
static void device_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
set a member's status based on device state of that member's interface
STASIS_MESSAGE_TYPE_DEFN_LOCAL(queue_caller_join_type,.to_ami=queue_caller_join_to_ami,)
int ast_channel_sendurl(struct ast_channel *channel, const char *url)
Sends a URL on a given link Send URL on link.
static struct call_queue * alloc_queue(const char *queuename)
struct ast_bridge_snapshot * bridge_snapshot
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
int source
Information about the source of an update.
#define ast_calloc(num, len)
A wrapper for calloc()
static char * complete_queue_remove_member(const char *line, const char *word, int pos, int state)
struct local_optimization member_optimize
const char * ast_term_reset(void)
Returns the terminal reset code.
static int queue_function_queuegetchannel(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Dialplan function QUEUE_GET_CHANNEL() Get caller channel waiting at specified position in the queue...
static int manager_change_priority_caller_on_queue(struct mansession *s, const struct message *m)
static int play_file(struct ast_channel *chan, const char *filename)
#define queues_t_link(c, q, tag)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
struct penalty_rule::@68 list
static void to_ami(struct ast_sip_subscription *sub, struct ast_str **buf)
const ast_string_field moh
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
struct rule_list::@72 list
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
static char * complete_queue_add_member(const char *line, const char *word, int pos, int state)
Module has failed to load, may be in an inconsistent state.
int stasis_message_router_set_default(struct stasis_message_router *router, stasis_subscription_cb callback, void *data)
Sets the default route of a router.
static int manager_queues_status(struct mansession *s, const struct message *m)
Queue status info via AMI.
#define ao2_find(container, arg, flags)
const char * ast_term_color(int fgcolor, int bgcolor)
Return a color sequence string.
const ast_string_field uniqueid
const ast_string_field defaultrule
An API for managing task processing threads that can be shared across modules.
const ast_string_field sound_seconds
Basic bridge subclass API.
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
Structure used to handle boolean flags.
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
The waiting areas for callers who are not actively calling members.
unsigned int announceposition
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
static void queue_publish_multi_channel_blob(struct ast_channel *caller, struct ast_channel *agent, struct stasis_message_type *type, struct ast_json *blob)
static struct ast_manager_event_blob * queue_agent_called_to_ami(struct stasis_message *message)
static int manager_queues_summary(struct mansession *s, const struct message *m)
Summary of queue info via the AMI.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
int randomperiodicannounce
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static int queue_function_queuememberlist(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Dialplan function QUEUE_MEMBER_LIST() Get list of members in a specific queue.
#define ANNOUNCEHOLDTIME_ALWAYS
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
void(* end_bridge_callback)(void *)
unsigned int setqueueentryvar
#define queue_t_unref(q, tag)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
static struct ast_manager_event_blob * queue_member_to_ami(const char *type, struct stasis_message *message)
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
static struct ast_cli_entry cli_queue[]
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
const ast_string_field announce
const ast_string_field sound_reporthold
static void callattempt_free(struct callattempt *doomed)
static int set_member_value_help_members(struct call_queue *q, const char *interface, int property, int value)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Assume that the ao2_container is already locked.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
The arg parameter is an object of the same type.
int transit_network_select
Transit Network Select.
#define ANNOUNCEPOSITION_LIMIT
static int store_next_lin(struct queue_ent *qe, struct callattempt *outgoing)
Search for best metric and add to Linear queue.
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
char * strsep(char **str, const char *delims)
static void record_abandoned(struct queue_ent *qe)
Record that a caller gave up on waiting in queue.
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
static void send_agent_complete(const char *queuename, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer, const struct member *member, time_t holdstart, time_t callstart, enum agent_complete_reason rsn)
Send out AMI message with member call completion status information.
const ast_string_field sound_calls
After Bridge Execution API.
static int realtime_rules
queuesrules.conf [general] option
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Standard Command Line Interface.
static struct call_queue * find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
Reload a single queue via realtime.
time_t last_periodic_announce_time
void AST_OPTIONAL_API_NAME() ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon)
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
static struct ast_custom_function queuevar_function
int ast_channel_hangupcause(const struct ast_channel *chan)
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
static void queue_rules_reset_global_params(void)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
Uses hint and devicestate callback to get the state of an extension.
static void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
Insert the 'new' entry after the 'prev' entry of queue 'q'.
static int autopause2int(const char *autopause)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
ast_app: A registered application
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
static void handle_local_optimization_begin(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static struct member * get_interface_helper(struct call_queue *q, const char *interface)
static int get_member_status(struct call_queue *q, int max_penalty, int min_penalty, int raise_penalty, enum empty_conditions conditions, int devstate)
Check if members are available.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
static int compress_char(const char c)
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
static void set_queue_variables(struct call_queue *q, struct ast_channel *chan)
Set variables of queue.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
A multi channel blob data structure for multi_channel_blob stasis messages.
static int aqm_exec(struct ast_channel *chan, const char *data)
AddQueueMember application.
static void hangupcalls(struct queue_ent *qe, struct callattempt *outgoing, struct ast_channel *exception, int cancel_answered_elsewhere)
Hang up a list of outgoing calls.
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.
User data for stasis subscriptions used for queue calls.
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
#define ao2_t_find(container, arg, flags, tag)
char state_context[AST_MAX_CONTEXT]
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
struct stasis_forward * sub
Data structure associated with a single frame of data.
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Internal Asterisk hangup causes.
static int pending_members_cmp(void *obj, void *arg, int flags)
const char * ast_channel_language(const struct ast_channel *chan)
enum empty_conditions leavewhenempty
static int use_weight
Records that one or more queues use weight.
Abstract JSON element (object, array, string, int, ...).
struct queue_ent::@67 qe_rules
#define AST_OPTION_TONE_VERIFY
static void reload_single_queue(struct ast_config *cfg, struct ast_flags *mask, const char *queuename)
Reload information pertaining to a particular queue.
The structure that contains device state.
static struct ast_manager_event_blob * queue_agent_ringnoanswer_to_ami(struct stasis_message *message)
loadable MixMonitor functionality
const char * ast_channel_context(const struct ast_channel *chan)
Handy terminal functions for vt* terms.
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
static void print_queue(struct mansession *s, int fd, struct call_queue *q)
Print a single queue to AMI or the CLI.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
unsigned int relativeperiodicannounce
static int get_queue_member_status(struct member *cur)
Return the current state of a member.
union ast_frame::@263 data
static int publish_queue_member_pause(struct call_queue *q, struct member *member)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
static const char *const pm_family
Persistent Members astdb family.
static int queue_exec(struct ast_channel *chan, const char *data)
The starting point for all queue calls.
static void reload_queue_members(void)
Reload dynamic queue members persisted into the astdb.
static void queue_agent_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
const ast_string_field sound_minutes
static void remove_stasis_subscriptions(struct queue_stasis_data *queue_data)
static int queue_hash_cb(const void *obj, const int flags)
char context[AST_MAX_CONTEXT]
static void do_hang(struct callattempt *o)
common hangup actions
struct callattempt * call_next
unsigned char valid
TRUE if the name information is valid/present.
static int manager_add_queue_member(struct mansession *s, const struct message *m)
static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_args, char *announceoverride, const char *url, int *tries, int *noption, const char *agi, const char *macro, const char *gosub, int ringing)
const ast_string_field queue_quantity2
Search option field mask.
static char context[AST_MAX_CONTEXT]
static void init_queue(struct call_queue *q)
Initialize Queue default values.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
int cancel_answered_elsewhere
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ANNOUNCEHOLDTIME_ONCE
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
static int queue_function_queuewaitingcount(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Dialplan function QUEUE_WAITING_COUNT() Get number callers waiting in a specific queue.
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Add watcher for extension states.
static int remove_from_queue(const char *queuename, const char *interface)
Remove member from queue.
static int set_member_value(const char *queuename, const char *interface, int property, int value)
struct stasis_topic * ast_queue_topic(const char *queuename)
Get the Stasis Message Bus API topic for queue messages for a particular queue name.
static char * handle_queue_reset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void copy_rules(struct queue_ent *qe, const char *rulename)
Copy rule from global list into specified queue.
static void queue_member_follower_removal(struct call_queue *queue, struct member *mem)
static struct queue_stasis_data * queue_stasis_data_alloc(struct queue_ent *qe, struct ast_channel *peer, struct member *mem, time_t holdstart, time_t starttime, int callcompletedinsl)
struct ast_app * pbx_findapp(const char *app)
Look up an application.
struct stasis_message_type * ast_channel_hangup_request_type(void)
Message type for when a hangup is requested on a channel.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
static void update_qe_rule(struct queue_ent *qe)
update rules for queues
Say numbers and dates (maybe words one day too)
static const struct autopause autopausesmodes[]
#define ASTERISK_GPL_KEY
The text the key() function should return.
unsigned int dial_callerid_absent
enum empty_conditions joinempty
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
static char * handle_queue_set_member_penalty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_channel * chan
const ast_string_field queue_quantity1
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Asterisk module definitions.
static int manager_pause_queue_member(struct mansession *s, const struct message *m)
static void setup_mixmonitor(struct queue_ent *qe, const char *filename)
static int is_our_turn(struct queue_ent *qe)
Check if we should start attempting to call queue members.
#define queues_t_unlink(c, q, tag)
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
struct stasis_message_type * ast_channel_masquerade_type(void)
Message type for when a channel is being masqueraded.
static struct stasis_subscription * device_state_sub
Subscription to device state change messages.
static struct ast_manager_event_blob * queue_agent_connect_to_ami(struct stasis_message *message)
static int kill_if_unfound(void *obj, void *arg, int flags)
static int valid_exit(struct queue_ent *qe, char digit)
Check for valid exit from queue via goto.
static int shared_lastcall
queues.conf [general] option
Persistant data storage (akin to *doze registry)
static char * handle_queue_pause_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct call_queue::@70 rules
const ast_string_field sound_callerannounce
AO2_STRING_FIELD_SORT_FN(call_queue, name)
unsigned char valid
TRUE if the number information is valid/present.
enum ast_transfer_result result
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static int set_member_penalty_help_members(struct call_queue *q, const char *interface, int penalty)
static int manager_remove_queue_member(struct mansession *s, const struct message *m)
#define ast_custom_function_register(acf)
Register a custom function.
const char * ast_channel_macroexten(const struct ast_channel *chan)
static const char * int2strat(int strategy)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump, const char *state_interface, const char *reason_paused, int wrapuptime)
Add member to queue.
int ast_stopstream(struct ast_channel *c)
Stops a stream.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
static int queue_persistent_members
queues.conf [general] option
static int reload_queues(int reload, struct ast_flags *mask, const char *queuename)
reload the queues.conf file
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
static char * complete_queue_show(const char *line, const char *word, int pos, int state)
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
static int clear_stats(const char *queuename)
Facilitates resetting statistics for a queue.
static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
Place a call to a queue member.
static void queue_publish_member_blob(struct stasis_message_type *type, struct ast_json *blob)
char state_exten[AST_MAX_EXTENSION]
const ast_string_field name
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
Run a redirecting interception macro and update a channel's redirecting information.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
static int load_realtime_rules(void)
Load queue rules from realtime.
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
struct ast_party_number number
Subscriber phone number.
#define ao2_link(container, obj)
static int is_member_available(struct call_queue *q, struct member *mem)
static void set_queue_member_pause(struct call_queue *q, struct member *mem, const char *reason, int paused)