72#include <netinet/in.h> 
 1680#define DEFAULT_RETRY       5 
 1681#define DEFAULT_TIMEOUT     15 
 1683#define MAX_PERIODIC_ANNOUNCEMENTS 10            
 1688#define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 
 1690#define MAX_QUEUE_BUCKETS 53 
 1693#define RES_EXISTS  (-1)         
 1694#define RES_OUTOFMEMORY (-2)         
 1695#define RES_NOSUCHQUEUE (-3)         
 1696#define RES_NOT_DYNAMIC (-4)         
 1697#define RES_NOT_CALLER  (-5)         
 1714static const char * 
const pm_family = 
"Queue/PersistentMembers";
 
 1770static const struct {
 
 1905#define ANNOUNCEHOLDTIME_ALWAYS 1 
 1906#define ANNOUNCEHOLDTIME_ONCE 2 
 1907#define QUEUE_EVENT_VARIABLES 3 
 1921#define ANNOUNCEPOSITION_YES 1  
 1922#define ANNOUNCEPOSITION_NO 2  
 1923#define ANNOUNCEPOSITION_MORE_THAN 3  
 1924#define ANNOUNCEPOSITION_LIMIT 4  
 2142    struct member *mem = obj;
 
 2143    int *decrement_followers_after = arg;
 
 2145    if (mem->
queuepos > *decrement_followers_after) {
 
 
 2161    struct member *mem = obj;
 
 
 2183    if (pos < queue->
rrpos) {
 
 
 2190#define queue_ref(q)                ao2_bump(q) 
 2191#define queue_unref(q)              ({ ao2_cleanup(q); NULL; }) 
 2192#define queue_t_ref(q, tag)         ao2_t_bump(q, tag) 
 2193#define queue_t_unref(q, tag)       ({ ao2_t_cleanup(q, tag); NULL; }) 
 2194#define queues_t_link(c, q, tag)    ao2_t_link(c, q, tag) 
 2195#define queues_t_unlink(c, q, tag)  ao2_t_unlink(c, q, tag) 
 2200    char interfacevar[256]=
"";
 
 2211        snprintf(interfacevar, 
sizeof(interfacevar),
 
 2212            "QUEUENAME=%s,QUEUEMAX=%d,QUEUESTRATEGY=%s,QUEUECALLS=%d,QUEUEHOLDTIME=%d,QUEUETALKTIME=%d,QUEUECOMPLETED=%d,QUEUEABANDONED=%d,QUEUESRVLEVEL=%d,QUEUESRVLEVELPERF=%2.1f",
 
 
 2246    new->pos = ++(*pos);
 
 
 2258    if (!channel_string || !event_string) {
 
 
 2300    if (!event_string) {
 
 
 2370        if (!caller_event_string) {
 
 2379        if (!agent_event_string) {
 
 2386    if (!event_string) {
 
 
 2457    if (caller_snapshot) {
 
 2460        ast_debug(1, 
"Empty caller_snapshot; sending incomplete event\n");
 
 2463    if (agent_snapshot) {
 
 
 2488    if (!caller_snapshot || !agent_snapshot) {
 
 2493            agent_snapshot, 
type, blob);
 
 
 2511    if (!blob || !
type) {
 
 
 2532    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: i, s: s, s: i, s: i}",
 
 2537        "Membership", (mem->
dynamic ? 
"dynamic" : (mem->
realtime ? 
"realtime" : 
"static")),
 
 2539        "CallsTaken", mem->
calls,
 
 
 2566        if (raise_penalty != INT_MAX && penalty < raise_penalty) {
 
 2568            if (raise_respect_min && penalty < min_penalty) {
 
 2572                penalty = raise_penalty;
 
 2575        if ((max_penalty != INT_MAX && penalty > max_penalty) || (min_penalty != INT_MAX && penalty < min_penalty)) {
 
 2577                ast_debug(4, 
"%s is unavailable because his penalty is not between %d and %d\n", 
member->
membername, min_penalty, max_penalty);
 
 2622                ast_debug(4, 
"%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n",
 
 2640        return get_member_status(q, max_penalty, min_penalty, raise_penalty, conditions, 1, raise_respect_min);
 
 
 2654#define MAX_CALL_ATTEMPT_BUCKETS 353 
 2658    const struct member *object;
 
 
 2678    const struct member *object_left = obj;
 
 2679    const struct member *object_right = arg;
 
 2680    const char *right_key = arg;
 
 2688        cmp = strcasecmp(object_left->
interface, right_key);
 
 
 2787    char interface[80], *slash_pos;
 
 2797    if (dev_state->
eid) {
 
 2810            if (!found_member) {
 
 2813                if ((slash_pos = strchr(interface, 
'/'))) {
 
 2814                    if (!strncasecmp(interface, 
"Local/", 6) && (slash_pos = strchr(slash_pos + 1, 
'/'))) {
 
 2819                if (!strcasecmp(interface, dev_state->
device)) {
 
 2829            if (avail && found_member) {
 
 2853        ast_debug(1, 
"Device '%s' changed to state '%u' (%s)\n",
 
 2858        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",
 
 
 2933            if (!strcasecmp(child, includename)) {
 
 
 2951    int state = info->exten_state;
 
 2982        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",
 
 
 2997    struct member *mem = obj;
 
 
 3034            char *exten = 
strsep(&context, 
"@") + 5;
 
 
 3054    } 
else if (
c > 96) {
 
 
 3062    const struct member *mem = obj;
 
 3064    const char *chname = strchr(interface, 
'/');
 
 3070    for (i = 0; i < 5 && chname[i]; i++) {
 
 
 3078    struct member *mem1 = obj1;
 
 3079    struct member *mem2 = obj2;
 
 
 3225    char *timestr, *maxstr, *minstr, *raisestr, *contentdup;
 
 3228    int penaltychangetime, inserted = 0;
 
 3236    if (!(maxstr = strchr(contentdup, 
','))) {
 
 3237        ast_log(
LOG_WARNING, 
"Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
 
 3243    if ((minstr = strchr(maxstr,
','))) {
 
 3245        if ((raisestr = strchr(minstr,
','))) {
 
 3252    timestr = contentdup;
 
 3253    if ((penaltychangetime = atoi(timestr)) < 0) {
 
 3254        ast_log(
LOG_WARNING, 
"Improper time parameter specified for penaltychange rule at line %d. Ignoring.\n", linenum);
 
 3259    rule->time = penaltychangetime;
 
 3263    if (*maxstr == 
'+' || *maxstr == 
'-' || *maxstr == 
'\0') {
 
 3264        rule->max_relative = 1;
 
 3267    rule->max_value = atoi(maxstr);
 
 3270        if (*minstr == 
'+' || *minstr == 
'-') {
 
 3271            rule->min_relative = 1;
 
 3273        rule->min_value = atoi(minstr);
 
 3275        rule->min_relative = 1;
 
 3279        rule->raise_respect_min = 0;  
 
 3280        if (*raisestr == 
'r') {
 
 3281            rule->raise_respect_min = 1;               
 
 3284        if (*raisestr == 
'+' || *raisestr == 
'-') {
 
 3285            rule->raise_relative = 1;
 
 3287        rule->raise_value = atoi(raisestr);
 
 3289        rule->raise_relative = 1;
 
 3294        if (strcasecmp(rl_iter->
name, list_name)) {
 
 3299            if (
rule->time < rule_iter->time) {
 
 
 3337        char *rulecat = 
NULL;
 
 3348        const char *timestr, *maxstr, *minstr, *raisestr, *rule_name;
 
 3349        int penaltychangetime, rule_exists = 0, inserted = 0;
 
 3350        int max_penalty = 0, min_penalty = 0, raise_penalty = 0;
 
 3360            if (!(strcasecmp(rl_iter->
name, rule_name))) {
 
 3367            if (!(new_rl = 
ast_calloc(1, 
sizeof(*new_rl)))) {
 
 3375        if (!(timestr) || sscanf(timestr, 
"%30d", &penaltychangetime) != 1) {
 
 3376            ast_log(
LOG_NOTICE, 
"Failed to parse time (%s) for one of the %s rules, skipping it\n",
 
 3380        if (!(new_penalty_rule = 
ast_calloc(1, 
sizeof(*new_penalty_rule)))) {
 
 3385            ast_strlen_zero(maxstr) || sscanf(maxstr, 
"%30d", &max_penalty) != 1) {
 
 3389            if (*maxstr == 
'+' || *maxstr == 
'-') {
 
 3394            ast_strlen_zero(minstr) || sscanf(minstr, 
"%30d", &min_penalty) != 1) {
 
 3398            if (*minstr == 
'+' || *minstr == 
'-') {
 
 3407            if (*raisestr == 
'r') {
 
 3413            if (*raisestr == 
'+' || *raisestr == 
'-') {
 
 3416            if (sscanf(raisestr, 
"%30d", &raise_penalty) != 1) {
 
 3421        new_penalty_rule->
time = penaltychangetime;
 
 3423        new_penalty_rule->
max_value = max_penalty;
 
 3425        new_penalty_rule->
min_value = min_penalty;
 
 3429            if (new_penalty_rule->
time < pr_iter->
time) {
 
 
 3447    char *option = 
NULL;
 
 3448    while ((option = 
strsep(&value_copy, 
","))) {
 
 3449        if (!strcasecmp(option, 
"paused")) {
 
 3451        } 
else if (!strcasecmp(option, 
"penalty")) {
 
 3453        } 
else if (!strcasecmp(option, 
"inuse")) {
 
 3455        } 
else if (!strcasecmp(option, 
"ringing")) {
 
 3457        } 
else if (!strcasecmp(option, 
"invalid")) {
 
 3459        } 
else if (!strcasecmp(option, 
"wrapup")) {
 
 3461        } 
else if (!strcasecmp(option, 
"unavailable")) {
 
 3463        } 
else if (!strcasecmp(option, 
"unknown")) {
 
 3465        } 
else if (!strcasecmp(option, 
"loose")) {
 
 3467        } 
else if (!strcasecmp(option, 
"strict")) {
 
 3469        } 
else if ((
ast_false(option) && joinempty) || (
ast_true(option) && !joinempty)) {
 
 3471        } 
else if ((
ast_false(option) && !joinempty) || (
ast_true(option) && joinempty)) {
 
 3474            ast_log(
LOG_WARNING, 
"Unknown option %s for '%s'\n", option, joinempty ? 
"joinempty" : 
"leavewhenempty");
 
 
 3489    if (!strcasecmp(param, 
"musicclass") ||
 
 3490        !strcasecmp(param, 
"music") || !strcasecmp(param, 
"musiconhold")) {
 
 3492    } 
else if (!strcasecmp(param, 
"announce")) {
 
 3494    } 
else if (!strcasecmp(param, 
"context")) {
 
 3496    } 
else if (!strcasecmp(param, 
"timeout")) {
 
 3501    } 
else if (!strcasecmp(param, 
"ringinuse")) {
 
 3503    } 
else if (!strcasecmp(param, 
"setinterfacevar")) {
 
 3505    } 
else if (!strcasecmp(param, 
"setqueuevar")) {
 
 3507    } 
else if (!strcasecmp(param, 
"setqueueentryvar")) {
 
 3509    } 
else if (!strcasecmp(param, 
"monitor-format")) {
 
 3511    } 
else if (!strcasecmp(param, 
"membergosub")) {
 
 3513    } 
else if (!strcasecmp(param, 
"queue-youarenext")) {
 
 3515    } 
else if (!strcasecmp(param, 
"queue-thereare")) {
 
 3517    } 
else if (!strcasecmp(param, 
"queue-callswaiting")) {
 
 3519    } 
else if (!strcasecmp(param, 
"queue-quantity1")) {
 
 3521    } 
else if (!strcasecmp(param, 
"queue-quantity2")) {
 
 3523    } 
else if (!strcasecmp(param, 
"queue-holdtime")) {
 
 3525    } 
else if (!strcasecmp(param, 
"queue-minutes")) {
 
 3527    } 
else if (!strcasecmp(param, 
"queue-minute")) {
 
 3529    } 
else if (!strcasecmp(param, 
"queue-seconds")) {
 
 3531    } 
else if (!strcasecmp(param, 
"queue-thankyou")) {
 
 3533    } 
else if (!strcasecmp(param, 
"queue-callerannounce")) {
 
 3535    } 
else if (!strcasecmp(param, 
"queue-reporthold")) {
 
 3537    } 
else if (!strcasecmp(param, 
"announce-frequency")) {
 
 3539    } 
else if (!strcasecmp(param, 
"announce-to-first-user")) {
 
 3541    } 
else if (!strcasecmp(param, 
"min-announce-frequency")) {
 
 3544    } 
else if (!strcasecmp(param, 
"announce-round-seconds")) {
 
 3551                    "using 0 instead for queue '%s' at line %d of queues.conf\n",
 
 3552                    val, param, q->
name, linenum);
 
 3555                    "using 0 instead for queue '%s'\n", 
val, param, q->
name);
 
 3559    } 
else if (!strcasecmp(param, 
"announce-holdtime")) {
 
 3560        if (!strcasecmp(
val, 
"once")) {
 
 3567    } 
else if (!strcasecmp(param, 
"announce-position")) {
 
 3568        if (!strcasecmp(
val, 
"limit")) {
 
 3570        } 
else if (!strcasecmp(
val, 
"more")) {
 
 3577    } 
else if (!strcasecmp(param, 
"announce-position-only-up")) {
 
 3579    } 
else if (!strcasecmp(param, 
"announce-position-limit")) {
 
 3581    } 
else if (!strcasecmp(param, 
"periodic-announce")) {
 
 3582        if (strchr(
val, 
',')) {
 
 3601    } 
else if (!strcasecmp(param, 
"periodic-announce-startdelay")) {
 
 3603    } 
else if (!strcasecmp(param, 
"periodic-announce-frequency")) {
 
 3605    } 
else if (!strcasecmp(param, 
"relative-periodic-announce")) {
 
 3607    } 
else if (!strcasecmp(param, 
"random-periodic-announce")) {
 
 3609    } 
else if (!strcasecmp(param, 
"retry")) {
 
 3611        if (q->
retry <= 0) {
 
 3614    } 
else if (!strcasecmp(param, 
"wrapuptime")) {
 
 3616    } 
else if (!strcasecmp(param, 
"penaltymemberslimit")) {
 
 3620    } 
else if (!strcasecmp(param, 
"autofill")) {
 
 3622    } 
else if (!strcasecmp(param, 
"autopause")) {
 
 3624    } 
else if (!strcasecmp(param, 
"autopausedelay")) {
 
 3626    } 
else if (!strcasecmp(param, 
"autopausebusy")) {
 
 3628    } 
else if (!strcasecmp(param, 
"autopauseunavail")) {
 
 3630    } 
else if (!strcasecmp(param, 
"maxlen")) {
 
 3635    } 
else if (!strcasecmp(param, 
"servicelevel")) {
 
 3637    } 
else if (!strcasecmp(param, 
"strategy")) {
 
 3646            ast_log(
LOG_WARNING, 
"'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
 
 3654            ast_log(
LOG_WARNING, 
"Changing to the linear strategy currently requires asterisk to be restarted.\n");
 
 3658    } 
else if (!strcasecmp(param, 
"joinempty")) {
 
 3660    } 
else if (!strcasecmp(param, 
"leavewhenempty")) {
 
 3662    } 
else if (!strcasecmp(param, 
"reportholdtime")) {
 
 3664    } 
else if (!strcasecmp(param, 
"memberdelay")) {
 
 3666    } 
else if (!strcasecmp(param, 
"weight")) {
 
 3668    } 
else if (!strcasecmp(param, 
"timeoutrestart")) {
 
 3670    } 
else if (!strcasecmp(param, 
"defaultrule")) {
 
 3672    } 
else if (!strcasecmp(param, 
"timeoutpriority")) {
 
 3673        if (!strcasecmp(
val, 
"conf")) {
 
 3678    } 
else if (!strcasecmp(param, 
"log-restricted-caller-id")) {
 
 3680    } 
else if (failunknown) {
 
 3682            ast_log(
LOG_WARNING, 
"Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
 
 3683                q->
name, param, linenum);
 
 
 3691#define QUEUE_PAUSED_DEVSTATE AST_DEVICE_INUSE 
 3692#define QUEUE_UNPAUSED_DEVSTATE AST_DEVICE_NOT_INUSE 
 3693#define QUEUE_UNKNOWN_PAUSED_DEVSTATE AST_DEVICE_NOT_INUSE 
 3743    const char *config_val;
 
 3755            S_OR(membername, 
"NULL"));
 
 3761            S_OR(membername, 
"NULL"));
 
 3766        penalty = atoi(penalty_str);
 
 3769        } 
else if (penalty < 0) {
 
 3775        paused = atoi(paused_str);
 
 3781    if (wrapuptime_str) {
 
 3782        wrapuptime = atoi(wrapuptime_str);
 
 3783        if (wrapuptime < 0) {
 
 3831        if ((m = 
create_queue_member(interface, membername, penalty, paused, state_interface, ringinuse, wrapuptime))) {
 
 
 3914    char *category = 
NULL;
 
 3915    const char *tmp_name;
 
 3932    } 
else if (!member_config) {
 
 3943            ast_debug(1, 
"Queue %s not found in realtime.\n", queuename);
 
 3966        for (tmpvar = queue_vars; tmpvar; tmpvar = tmpvar->
next) {
 
 3967            if (!strcasecmp(tmpvar->
name, 
"strategy")) {
 
 3970                    ast_log(
LOG_WARNING, 
"'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
 
 3985    memset(tmpbuf, 0, 
sizeof(tmpbuf));
 
 3986    for (v = queue_vars; v; v = v->
next) {
 
 3988        if (strchr(v->
name, 
'_')) {
 
 3992            while ((tmp = strchr(tmp, 
'_'))) {
 
 
 4057    int prev_weight = 0;
 
 4075            if (!member_config) {
 
 4076                ast_debug(1, 
"No queue_members defined in config extconfig.conf\n");
 
 4081            prev_weight = q->
weight ? 1 : 0;
 
 4091            if (!q->
weight && prev_weight) {
 
 4094            if (q->
weight && !prev_weight) {
 
 
 4114    char *category = 
NULL;
 
 
 4159    char *category = 
NULL;
 
 4175        ast_debug(3, 
"Queue %s has no realtime members defined. No need for update\n", q->
name);
 
 
 4259            if (!
inserted && (
qe->prio >= cur->
prio) && position && (position <= 
pos + 1)) {
 
 4263                if (position < 
pos) {
 
 4264                    ast_log(
LOG_NOTICE, 
"Asked to be inserted at position %d but forced into position %d due to higher priority callers\n", position, 
pos);
 
 4279        if (q->
count == 1) {
 
 4287                     "Position", 
qe->pos,
 
 
 4332    if (digitlen < 
sizeof(
qe->digits) - 2) {
 
 4334        qe->digits[digitlen + 1] = 
'\0';
 
 4336        qe->digits[0] = 
'\0';
 
 4348        qe->digits[0] = 
'\0';
 
 4354        qe->valid_digits = 1;
 
 
 4370    if ((
now - 
qe->last_pos) < 
qe->parent->minannouncefrequency) {
 
 4375    if ((
qe->last_pos_said == 
qe->pos) && ((
now - 
qe->last_pos) < 
qe->parent->announcefrequency)) {
 
 4380    if (
qe->parent->announceposition_only_up && 
qe->last_pos_said > 0 && 
qe->last_pos_said <= 
qe->pos) {
 
 4393        qe->pos <= 
qe->parent->announcepositionlimit)) {
 
 4424    if (
qe->parent->roundingseconds) {
 
 4476    if (
qe->parent->announceposition) {
 
 4477        ast_verb(3, 
"Told %s in %s their queue position (which was %d)\n",
 
 4491    qe->last_pos_said = 
qe->pos;
 
 
 4513    if ((
qe->parent->callscompleted + 
qe->parent->callsabandoned) == 0) {
 
 
 4537    queue_t_ref(q, 
"Copy queue pointer from queue entry");
 
 4552                         "Position", qe->
pos,
 
 4567            snprintf(posstr, 
sizeof(posstr), 
"%d", qe->
pos);
 
 
 4617        if (cur->
chan && cur->
chan != exception) {
 
 
 4632            if (exception || cancel_answered_elsewhere) {
 
 
 4735    int is_longest_waiting = 1;
 
 4741        if (q == caller->
parent) { 
 
 4761                    if (
ch->start < caller->
start && !
ch->pending) {
 
 4762                        ast_debug(1, 
"Queue %s has a call at position %i that's been waiting longer (%li vs %li)\n",
 
 
 4818        ast_debug(1, 
"%s paused, can't receive call\n", 
call->interface);
 
 4823        ast_debug(1, 
"%s not available, can't receive call\n", 
call->interface);
 
 4833        ast_debug(1, 
"Wrapuptime not yet expired on queue %s for %s\n",
 
 4840        ast_debug(1, 
"Priority queue delaying call to %s:%s\n",
 
 4846        ast_debug(1, 
"Another caller was waiting longer; delaying call to %s:%s\n",
 
 4863            ast_debug(1, 
"%s has another call trying, can't receive call\n",
 
 4884            ast_debug(1, 
"%s actually not available, can't receive call\n",
 
 
 4925    if ((location = strchr(tech, 
'/'))) {
 
 
 5044    for (cur = 
outgoing; cur; cur = cur->q_next) {
 
 5045        if (cur->stillgoing &&                  
 
 
 5082            ast_debug(1, 
"Nobody left to try ringing in queue\n");
 
 5107            ast_debug(1, 
"Queue timed out while ringing members.\n");
 
 
 5193    ast_verb(3, 
"Playing periodic announcement\n");
 
 
 5236    int callabandonedinsl = 0;
 
 5247                 "Position", qe->
pos,
 
 5248                 "OriginalPosition", qe->
opos,
 
 5249                 "HoldTime", (
int)(time(
NULL) - qe->
start));
 
 5254    if (callabandonedinsl) {
 
 
 5269    ast_verb(3, 
"Nobody picked up in %d ms\n", rnatime);
 
 5280                 "MemberName", membername,
 
 5281                 "RingTime", rnatime);
 
 5290                time_t idletime = time(&idletime)-mem->
lastcall;
 
 5302                ast_verb(3, 
"Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n",
 
 5311                ast_verb(3, 
"Auto-Pausing Queue Member %s in all queues since they failed to answer on queue %s.\n",
 
 
 5346#define AST_MAX_WATCHERS 256 
 5365    int numbusies = prebusies;
 
 5374    char membername[80] = 
"";
 
 5378    struct timeval start_time_tv = 
ast_tvnow();
 
 5379    int canceled_by_caller = 0; 
 
 5385    starttime = (long) time(
NULL);
 
 5388        int numlines, retry, pos = 1;
 
 5393        for (retry = 0; retry < 2; retry++) {
 
 5400                            watchers[pos++] = o->
chan;
 
 5414            if (pos > 1  || !stillgoing  ||
 
 5424            if (numlines == (numbusies + numnochan)) {
 
 5425                ast_debug(1, 
"Everyone is busy at this time\n");
 
 5427                ast_debug(3, 
"No one is answering queue '%s' (%d numlines / %d busies / %d failed channels)\n", queue, numlines, numbusies, numnochan);
 
 5450                    ast_verb(3, 
"%s answered %s\n", ochan_name, inchan_name);
 
 5468                        size_t encoded_size;
 
 5477            } 
else if (o->
chan && (o->
chan == winner)) {
 
 5501                    if ((stuff = strchr(tmpchan, 
'/'))) {
 
 5505                        const char *forward_context;
 
 5513                    if (!strcasecmp(
tech, 
"Local")) {
 
 5522                    ast_verb(3, 
"Now forwarding %s to '%s/%s' (thanks to %s)\n", inchan_name, 
tech, stuff, ochan_name);
 
 5527                            "Forwarding failed to create channel to dial '%s/%s'\n",
 
 5632                                ast_verb(3, 
"%s answered %s\n", ochan_name, inchan_name);
 
 5652                                    size_t encoded_size;
 
 5663                            ast_verb(3, 
"%s is busy\n", ochan_name);
 
 5665                            endtime = (long) time(
NULL);
 
 5666                            endtime -= starttime;
 
 5676                                    starttime = (long) time(
NULL);
 
 5682                            ast_verb(3, 
"%s is circuit-busy\n", ochan_name);
 
 5684                            endtime = (long) time(
NULL);
 
 5685                            endtime -= starttime;
 
 5694                                    starttime = (long) time(
NULL);
 
 5700                            ast_verb(3, 
"%s is ringing\n", ochan_name);
 
 5715                                ast_verb(3, 
"Connected line update to %s prevented.\n", inchan_name);
 
 5721                                ast_verb(3, 
"%s connected line has changed. Saving it until answer for %s\n", ochan_name, inchan_name);
 
 5760                                ast_verb(3, 
"Redirecting update to %s prevented\n",
 
 5764                            ast_verb(3, 
"%s redirecting info has changed, passing it to %s\n",
 
 5765                                ochan_name, inchan_name);
 
 5780                    endtime = (long) time(
NULL) - starttime;
 
 5782                    rna(endtime * 1000, qe, o->
chan, on, membername, 1);
 
 5790                            starttime = (long) time(
NULL);
 
 5809                canceled_by_caller = 1;
 
 5814                canceled_by_caller = 1;
 
 5820                canceled_by_caller = 1;
 
 5823            if (canceled_by_caller) {
 
 
 5911    ch = 
qe->parent->head;
 
 5913    ast_debug(1, 
"There %s %d available %s.\n", 
avl != 1 ? 
"are" : 
"is", 
avl, 
avl != 1 ? 
"members" : 
"member");
 
 5927    if (
ch && 
idx < 
avl && (
qe->parent->autofill || 
qe->pos == 1)) {
 
 5936    if (
avl == 0 && 
qe->pos == 1) {
 
 
 5956        if (
qe->pr->max_relative) {
 
 5970        ast_debug(3, 
"Setting max penalty to %d for caller %s since %d seconds have elapsed\n",
 
 5978        if (
qe->pr->min_relative) {
 
 5996        ast_debug(3, 
"Setting min penalty to %d for caller %s since %d seconds have elapsed\n",
 
 6004        if (
qe->pr->raise_relative) {
 
 6022        ast_debug(3, 
"Setting raised penalty to %d for caller %s since %d seconds have elapsed\n",
 
 
 6058        if (
qe->expire && (time(
NULL) >= 
qe->expire)) {
 
 6063        if (
qe->parent->leavewhenempty) {
 
 6077        if (
qe->parent->announcefrequency &&
 
 6083        if (
qe->expire && (time(
NULL) >= 
qe->expire)) {
 
 6089        if (
qe->parent->periodicannouncefrequency &&
 
 6094        while (
qe->pr && ((time(
NULL) - 
qe->start) >= 
qe->pr->time)) {
 
 6099        if (
qe->expire && (time(
NULL) >= 
qe->expire)) {
 
 6114        if (
qe->expire && (time(
NULL) >= 
qe->expire)) {
 
 
 6177    if (callcompletedinsl) {
 
 6185        q->
talktime = (((oldtalktime << 2) - oldtalktime) + newtalktime) >> 2;
 
 
 6207        if (qe->
raise_penalty != INT_MAX && penalty < qe->raise_penalty) {
 
 6212            (qe->
min_penalty != INT_MAX && penalty < qe->min_penalty)) {
 
 6216        ast_debug(1, 
"Disregarding penalty, %d members and %d in penaltymemberslimit.\n",
 
 6223        tmp->
metric = penalty * 1000000 * usepenalty;
 
 6226        if (pos < qe->linpos) {
 
 6227            tmp->
metric = 1000 + pos;
 
 6235        tmp->
metric += penalty * 1000000 * usepenalty;
 
 6240        if (pos < q->rrpos) {
 
 6241            tmp->
metric = 1000 + pos;
 
 6243            if (pos > q->
rrpos) {
 
 6249        tmp->
metric += penalty * 1000000 * usepenalty;
 
 6253        tmp->
metric += penalty * 1000000 * usepenalty;
 
 6260        tmp->
metric += penalty * 1000000 * usepenalty;
 
 6268        tmp->
metric += penalty * 1000000 * usepenalty;
 
 
 6288    const char *reason = 
NULL;  
 
 6299        reason = 
"transfer";
 
 6303    blob = 
ast_json_pack(
"{s: s, s: s, s: s, s: I, s: I, s: s}",
 
 6309        "Reason", reason ?: 
"");
 
 6312            queue_agent_complete_type(), blob);
 
 
 6435    queue_data->
dying = 1;
 
 
 6470    queue_data->
member = mem;
 
 
 6490    if (!transfer_str) {
 
 
 6538    if (queue_data->
dying) {
 
 6549        ast_debug(3, 
"Detected entry of caller channel %s into bridge %s\n",
 
 
 6580    if (queue_data->
dying) {
 
 6601            "BLINDTRANSFER", 
"%s|%s|%ld|%ld|%d",
 
 
 6638    if (queue_data->
dying) {
 
 
 6709    if (!local_one || !local_two || !source) {
 
 6710        ast_debug(1, 
"Local optimization begin missing channel snapshots:%s%s%s\n",
 
 6711        !local_one ? 
" local_one," : 
"",
 
 6712        !local_two ? 
" local_two," : 
"", 
 
 6713        !source ? 
" source," : 
"");
 
 6717    if (queue_data->
dying) {
 
 6734        ast_log(
LOG_ERROR, 
"Unable to track local channel optimization for channel %s. Expect further errors\n", local_one->
base->
name);
 
 6739    optimization->
id = 
id;
 
 
 6768    if (queue_data->
dying) {
 
 6785        ast_log(
LOG_WARNING, 
"Told of a local optimization end when we had no previous begin\n");
 
 6789    if (
id != optimization->
id) {
 
 6790        ast_log(
LOG_WARNING, 
"Local optimization end event ID does not match begin (%u != %u)\n",
 
 6791                id, optimization->
id);
 
 6796        ast_debug(3, 
"Local optimization: Changing queue caller uniqueid from %s to %s\n",
 
 6800        ast_debug(3, 
"Local optimization: Changing queue member uniqueid from %s to %s\n",
 
 
 6832    if (queue_data->
dying) {
 
 6862    ast_debug(3, 
"Detected hangup of queue %s channel %s\n", reason == 
CALLER ? 
"caller" : 
"member",
 
 6866            reason == 
CALLER ? 
"COMPLETECALLER" : 
"COMPLETEAGENT", 
"%ld|%ld|%d",
 
 
 6882    const char *new_channel_id;
 
 6888    if (queue_data->
dying) {
 
 6894        ast_debug(1, 
"Replacing caller channel %s with %s due to masquerade\n", queue_data->
caller_uniqueid, new_channel_id);
 
 6897        ast_debug(1, 
"Replacing member channel %s with %s due to masquerade\n", queue_data->
member_uniqueid, new_channel_id);
 
 
 6937        time_t holdstart, time_t starttime, 
int callcompletedinsl)
 
 
 6994    qeb->
chan = originator;
 
 
 7038        char *output, 
size_t size)
 
 7040    const char *m = input;
 
 7044    for (p = escaped; p < escaped + size - 1; p++, m++) {
 
 7047            if (*(m + 1) == 
'{') {
 
 7061    if (p == escaped + size) {
 
 7062        escaped[size - 1] = 
'\0';
 
 
 7070    char escaped_filename[256];
 
 7071    char file_with_ext[
sizeof(escaped_filename) + 
sizeof(qe->
parent->
monfmt)];
 
 7072    char mixmonargs[1512];
 
 7073    char escaped_monitor_exec[1024];
 
 7074    const char *monitor_options;
 
 7075    const char *monitor_exec;
 
 7077    escaped_monitor_exec[0] = 
'\0';
 
 7092        monitor_options = 
"";
 
 7100    snprintf(file_with_ext, 
sizeof(file_with_ext), 
"%s.%s", escaped_filename, qe->
parent->
monfmt);
 
 7103        snprintf(mixmonargs, 
sizeof(mixmonargs), 
"b%s,%s", monitor_options, escaped_monitor_exec);
 
 7105        snprintf(mixmonargs, 
sizeof(mixmonargs), 
"b%s", monitor_options);
 
 7108    ast_debug(1, 
"Arguments being passed to MixMonitor: %s,%s\n", file_with_ext, mixmonargs);
 
 
 7148    char queuename[256]=
"";
 
 7153    int res = 0, bridge = 0;
 
 7156    char *announce = 
NULL;
 
 7158    time_t now = time(
NULL);
 
 7160    char nondataquality = 1;
 
 7161    char *agiexec = 
NULL;
 
 7162    char *gosubexec = 
NULL;
 
 7163    const char *monitorfilename;
 
 7164    int forwardsallowed = 1;
 
 7165    int block_connected_line = 0;
 
 7168    int callcompletedinsl;
 
 7171    memset(&bridge_config, 0, 
sizeof(bridge_config));
 
 7220        forwardsallowed = 0;
 
 7223        block_connected_line = 1;
 
 7243    ast_debug(1, 
"%s is trying to call a queue member.\n",
 
 7250        announce = announceoverride;
 
 7293            to = (qe->
expire - now) * 1000;
 
 7370                if (!res2 && announce) {
 
 7381                        long holdtime, holdtimesecs;
 
 7384                        holdtime = labs((now - qe->
start) / 60);
 
 7385                        holdtimesecs = labs((now - qe->
start) % 60);
 
 7392                        if (holdtimesecs > 1) {
 
 7462            ast_str_set(&interfacevar, 0, 
"MEMBERINTERFACE=%s,MEMBERNAME=%s,MEMBERCALLS=%d,MEMBERLASTCALL=%ld,MEMBERPENALTY=%d,MEMBERDYNAMIC=%d,MEMBERREALTIME=%d",
 
 7471            ast_str_set(&interfacevar, 0, 
"QEHOLDTIME=%ld,QEORIGINALPOS=%d",
 
 7512            char *gosub_args = 
NULL;
 
 7513            char *gosub_argstart;
 
 7515            ast_debug(1, 
"app_queue: gosub=%s.\n", gosubexec);
 
 7517            gosub_argstart = strchr(gosubexec, 
',');
 
 7518            if (gosub_argstart) {
 
 7519                const char *what_is_s = 
"s";
 
 7520                *gosub_argstart = 0;
 
 7523                    what_is_s = 
"~~s~~";
 
 7525                if (
ast_asprintf(&gosub_args, 
"%s,%s,1(%s)", gosubexec, what_is_s, gosub_argstart + 1) < 0) {
 
 7528                *gosub_argstart = 
',';
 
 7530                const char *what_is_s = 
"s";
 
 7533                    what_is_s = 
"~~s~~";
 
 7535                if (
ast_asprintf(&gosub_args, 
"%s,%s,1", gosubexec, what_is_s) < 0) {
 
 7543                ast_log(
LOG_ERROR, 
"Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
 
 7548            ast_debug(1, 
"app_queue: agi=%s.\n", agi);
 
 7554                ast_log(
LOG_WARNING, 
"Asked to execute an AGI on this channel, but could not find application (agi)!\n");
 
 7560                                                    (
long)(orig - to > 0 ? (orig - to) / 1000 : 0));
 
 7567                     "RingTime", (
ast_json_int_t)(orig - to > 0 ? (orig - to) / 1000 : 0));
 
 7599        res = bridge ? bridge : 1;
 
 
 7631        if (!strcasecmp(interface, mem->
interface)) {
 
 
 7650    struct member *cur_member;
 
 
 7708    struct member *mem, tmpmem;
 
 7722                queue_t_unref(q, 
"Interface wasn't dynamic, expiring temporary reference");
 
 
 7759    struct member *new_member, *old_member;
 
 
 7825            ast_debug(1, 
"%s Caller new priority %d in queue %s\n",
 
 7842        } 
else if (immediate) {
 
 
 7902                ast_debug(1, 
"Ignoring duplicate withdraw request of caller %s from queue %s\n", caller, 
queuename);
 
 
 7950    if (mem->
paused == paused) {
 
 7951        ast_debug(1, 
"%spausing already-%spaused queue member %s:%s\n",
 
 7952            (paused ? 
"" : 
"un"), (paused ? 
"" : 
"un"), q->
name, mem->
interface);
 
 7963                ast_log(
LOG_WARNING, 
"Failed update of realtime queue member %s:%s %spause and reason '%s'\n",
 
 7996            "Queue:%s_avail", q->
name);
 
 7999            "Queue:%s_avail", q->
name);
 
 
 8020static int set_member_paused(
const char *queuename, 
const char *interface, 
const char *reason, 
int paused)
 
 8049                        (
paused ? 
"PAUSEALL" : 
"UNPAUSEALL"), 
"%s", 
S_OR(reason, 
""));
 
 
 8083    int foundinterface = 0;
 
 8091            sprintf(rtpenalty, 
"%i", 
penalty);
 
 8103    return foundinterface;
 
 
 8132    int foundinterface = 0;
 
 8142    return foundinterface;
 
 
 8170    int foundinterface = 0, foundqueue = 0;
 
 8188                char *category = 
NULL;
 
 8222    if (foundinterface) {
 
 8224    } 
else if (!foundqueue) {
 
 
 8239    int foundqueue = 0, penalty;
 
 
 8271    const char *queue_name;
 
 8280    char *wrapuptime_tok;
 
 8290    for (entry = db_tree; entry; entry = entry->
next) {
 
 8308            ast_log(
LOG_WARNING, 
"Error loading persistent queue: '%s': it does not exist\n", queue_name);
 
 8318        cur_ptr = queue_data;
 
 8333                ast_log(
LOG_WARNING, 
"Error parsing persistent member string for '%s' (penalty)\n", queue_name);
 
 8336            penalty = strtol(penalty_tok, 
NULL, 10);
 
 8337            if (
errno == ERANGE) {
 
 8343                ast_log(
LOG_WARNING, 
"Error parsing persistent member string for '%s' (paused)\n", queue_name);
 
 8346            paused = strtol(paused_tok, 
NULL, 10);
 
 8347            if ((
errno == ERANGE) || paused < 0 || paused > 1) {
 
 8353                wrapuptime = strtol(wrapuptime_tok, 
NULL, 10);
 
 8354                if (
errno == ERANGE) {
 
 8355                    ast_log(
LOG_WARNING, 
"Error converting wrapuptime: %s: Out of range.\n", wrapuptime_tok);
 
 8360            ast_debug(1, 
"Reload Members: Queue: %s  Member: %s  Name: %s  Penalty: %d  Paused: %d ReasonPause: %s  Wrapuptime: %d\n",
 
 8361                          queue_name, interface, membername, penalty, paused, reason_paused, wrapuptime);
 
 8363            if (
add_to_queue(queue_name, interface, membername, penalty, paused, 0, state_interface, reason_paused, wrapuptime) == 
RES_OUTOFMEMORY) {
 
 8364                ast_log(
LOG_ERROR, 
"Out of Memory when reloading persistent queue member\n");
 
 
 8390        ast_log(
LOG_WARNING, 
"PauseQueueMember requires an argument ([queuename],interface[,options][,reason])\n");
 
 8399        ast_log(
LOG_WARNING, 
"Missing interface argument to PauseQueueMember ([queuename],interface[,options[,reason]])\n");
 
 
 8426        ast_log(
LOG_WARNING, 
"UnpauseQueueMember requires an argument ([queuename],interface[,options[,reason]])\n");
 
 8435        ast_log(
LOG_WARNING, 
"Missing interface argument to UnpauseQueueMember ([queuename],interface[,options[,reason]])\n");
 
 
 8454    char *parse, *temppos = 
NULL;
 
 8464        ast_log(
LOG_WARNING, 
"RemoveQueueMember requires an argument (queuename[,interface])\n");
 
 8474        temppos = strrchr(
args.interface, 
'-');
 
 8498        ast_debug(1, 
"Unable to remove interface '%s' from queue '%s': Not there\n", 
args.interface, 
args.queuename);
 
 8508        ast_log(
LOG_WARNING, 
"Unable to remove interface from queue '%s': '%s' is not a dynamic member\n", 
args.queuename, 
args.interface);
 
 
 8525    char *parse, *tmp, *temppos = 
NULL, *reason = 
NULL;
 
 8541        ast_log(
LOG_WARNING, 
"AddQueueMember requires an argument (queuename[,interface[,penalty[,options[,membername[,stateinterface][,wrapuptime]]]]])\n");
 
 8562        temppos = strrchr(
args.interface, 
'-');
 
 8569        if ((sscanf(
args.penalty, 
"%30d", &penalty) != 1) || penalty < 0) {
 
 8576        tmp = 
args.wrapuptime;
 
 8578        wrapuptime = atoi(tmp);
 
 8579        if (wrapuptime < 0) {
 
 
 8629        ast_log(
LOG_WARNING, 
"QueueLog requires arguments (queuename,uniqueid,membername,event[,additionalinfo]\n");
 
 8639        ast_log(
LOG_WARNING, 
"QueueLog requires arguments (queuename,uniqueid,membername,event[,additionalinfo])\n");
 
 8644        "%s", 
args.params ? 
args.params : 
"");
 
 
 8657        if (!strcasecmp(rl_iter->
name, tmp)) {
 
 8665                ast_log(
LOG_ERROR, 
"Memory allocation error when copying penalty rules! Aborting!\n");
 
 
 8697    const char *user_priority;
 
 8698    const char *max_penalty_str;
 
 8699    const char *min_penalty_str;
 
 8700    const char *raise_penalty_str;
 
 8703    int max_penalty, min_penalty, raise_penalty;
 
 8709    int makeannouncement = 0;
 
 8730        ast_log(
LOG_WARNING, 
"Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,gosub[,rule[,position]]]]]]]]\n");
 
 8746    ast_debug(1, 
"queue: %s, options: %s, url: %s, announce: %s, timeout: %s, agi: %s, gosub: %s, rule: %s, position: %s\n",
 
 8776    if (user_priority) {
 
 8777        if (sscanf(user_priority, 
"%30d", &prio) == 1) {
 
 8785        ast_debug(3, 
"NO QUEUE_PRIO variable found. Using default.\n");
 
 8792        if (sscanf(max_penalty_str, 
"%30d", &max_penalty) == 1) {
 
 8797            max_penalty = INT_MAX;
 
 8800        max_penalty = INT_MAX;
 
 8804        if (sscanf(min_penalty_str, 
"%30d", &min_penalty) == 1) {
 
 8809            min_penalty = INT_MAX;
 
 8812        min_penalty = INT_MAX;
 
 8816         if (*raise_penalty_str == 
'r') {
 
 8818            raise_penalty_str++;
 
 8822        if (sscanf(raise_penalty_str, 
"%30d", &raise_penalty) == 1) {
 
 8827            raise_penalty = INT_MAX;
 
 8830        raise_penalty = INT_MAX;
 
 8846    if (
args.position) {
 
 8847        position = atoi(
args.position);
 
 8849            ast_log(
LOG_WARNING, 
"Invalid position '%s' given for call to queue '%s'. Assuming no preference for position\n", 
args.position, 
args.queuename);
 
 8854    ast_debug(1, 
"queue: %s, expires: %ld, priority: %d\n",
 
 8882        char *escaped_cidname = 
NULL;
 
 8887            if (strchr(escaped_cidname, 
'|')) {
 
 8888                for (
char *p = escaped_cidname; *p; p++) {
 
 8900            S_OR(escaped_cidname, 
""));
 
 8968        if (makeannouncement) {
 
 8976        makeannouncement = 1;
 
 9026            ast_verb(3, 
"Exiting on time-out cycle\n");
 
 9073        } 
else if (res < 0) {
 
 9083            } 
else if (qcontinue) {
 
 
 9137    char interfacevar[256] = 
"";
 
 9155            snprintf(interfacevar, 
sizeof(interfacevar),
 
 9156                "QUEUEMAX=%d,QUEUESTRATEGY=%s,QUEUECALLS=%d,QUEUEHOLDTIME=%d,QUEUETALKTIME=%d,QUEUECOMPLETED=%d,QUEUEABANDONED=%d,QUEUESRVLEVEL=%d,QUEUESRVLEVELPERF=%2.1f",
 
 9168    snprintf(
buf, 
len, 
"%d", res);
 
 
 9190        queue_t_unref(q, 
"Done with temporary reference in QUEUE_EXISTS()");
 
 
 9201        ast_log(
LOG_ERROR, 
"QUEUE_MEMBER: Missing required interface argument.\n");
 
 
 9236            "Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
 
 9245            "Missing required argument. %s(<queuename>,<option>[,<interface>])\n",
 
 9252        if (!strcasecmp(
args.option, 
"logged")) {
 
 9262        } 
else if (!strcasecmp(
args.option, 
"free")) {
 
 9272        } 
else if (!strcasecmp(
args.option, 
"ready")) {
 
 9285        } 
else if (!strcasecmp(
args.option, 
"count")) {
 
 9287        } 
else if (!strcasecmp(
args.option, 
"penalty")) {
 
 9293        } 
else if (!strcasecmp(
args.option, 
"paused")) {
 
 9299        } 
else if ((!strcasecmp(
args.option, 
"ignorebusy") 
 
 9300            || !strcasecmp(
args.option, 
"ringinuse"))) {
 
 9310        queue_t_unref(q, 
"Done with temporary reference in QUEUE_MEMBER()");
 
 
 9333            "Missing required argument. %s([<queuename>],<option>,<interface>)\n",
 
 9343            "Missing required argument. %s([<queuename>],<option>,<interface>)\n",
 
 9353    memvalue = atoi(
value);
 
 9354    if (!strcasecmp(
args.option, 
"penalty")) {
 
 9359    } 
else if (!strcasecmp(
args.option, 
"paused")) {
 
 9360        memvalue = (memvalue <= 0) ? 0 : 1;
 
 9365    } 
else if (!strcasecmp(
args.option, 
"ignorebusy") 
 
 9366        || !strcasecmp(
args.option, 
"ringinuse")) {
 
 9367        memvalue = (memvalue <= 0) ? 0 : 1;
 
 
 9395        ast_log(
LOG_ERROR, 
"Missing argument. QUEUE_GET_CHANNEL(<queuename>,<position>)\n");
 
 9410        if (sscanf(
args.position, 
"%30d", &position) != 1) {
 
 9415            ast_log (
LOG_ERROR, 
"<position> parameter must be an integer greater than zero.\n");
 
 9429        if (q->
count >= position) {
 
 9433                if (
qe->pos == position) {
 
 9440        queue_t_unref(q, 
"Done with reference in QUEUE_GET_CHANNEL()");
 
 
 9470        ast_log(
LOG_ERROR, 
"QUEUE_WAITING_COUNT requires an argument: queuename\n");
 
 9478        queue_t_unref(q, 
"Done with reference in QUEUE_WAITING_COUNT()");
 
 9490    snprintf(
buf, 
len, 
"%d", count);
 
 
 9510        int buflen = 0, count = 0;
 
 9518                strncat(
buf + buflen, 
",", 
len - buflen - 1);
 
 9524            if (buflen >= 
len - 2) {
 
 
 9555        ast_log(
LOG_ERROR, 
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
 
 9561    if (
args.argc < 2) {
 
 9562        ast_log(
LOG_ERROR, 
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
 
 9569        snprintf (
buf, 
len, 
"%d", penalty);
 
 
 9585        ast_log(
LOG_ERROR, 
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
 
 9591    if (
args.argc < 2) {
 
 9592        ast_log(
LOG_ERROR, 
"Missing argument. QUEUE_MEMBER_PENALTY(<queuename>,<interface>)\n");
 
 9596    penalty = atoi(
value);
 
 
 9613    .
name = 
"QUEUE_EXISTS",
 
 
 9618    .
name = 
"QUEUE_VARIABLES",
 
 
 9623    .
name = 
"QUEUE_MEMBER",
 
 
 9629    .
name = 
"QUEUE_GET_CHANNEL",
 
 
 9634    .
name = 
"QUEUE_WAITING_COUNT",
 
 
 9639    .
name = 
"QUEUE_MEMBER_LIST",
 
 
 9644    .
name = 
"QUEUE_MEMBER_PENALTY",
 
 
 9658    const char *general_val = 
NULL;
 
 
 9675    char *rulecat = 
NULL;
 
 9680        ast_log(
LOG_NOTICE, 
"No queuerules.conf file found, queues will not follow penalty rules\n");
 
 9683        ast_log(
LOG_NOTICE, 
"queuerules.conf has not changed since it was last loaded. Not taking any action.\n");
 
 9686        ast_log(
LOG_ERROR, 
"Config file queuerules.conf is in an invalid format.  Aborting.\n");
 
 9698        if (!strcasecmp(rulecat, 
"general")) {
 
 9702        if (!(new_rl = 
ast_calloc(1, 
sizeof(*new_rl)))) {
 
 9710                if(!strcasecmp(rulevar->
name, 
"penaltychange"))
 
 
 9744    const char *general_val = 
NULL;
 
 9752        if (!strcasecmp(general_val, 
"mixmonitor"))
 
 
 9786    char *membername, *interface, *state_interface, *tmp;
 
 9788    struct member *cur, *newm;
 
 9814    interface = args.interface;
 
 9818        penalty = atoi(tmp);
 
 9827        membername = 
args.membername;
 
 9830        membername = interface;
 
 9834        state_interface = 
args.state_interface;
 
 9837        state_interface = interface;
 
 9841        tmp = 
args.ringinuse;
 
 9848            ast_log(
LOG_ERROR, 
"Member %s has an invalid ringinuse value. Using %s ringinuse value.\n",
 
 9849                membername, q->
name);
 
 9857        tmp = 
args.wrapuptime;
 
 9859        wrapuptime = atoi(tmp);
 
 9860        if (wrapuptime < 0) {
 
 9875            ast_log(
LOG_ERROR, 
"Member %s has an invalid paused value.\n", membername);
 
 9890    if ((newm = 
create_queue_member(interface, membername, penalty, paused, state_interface, ringinuse, wrapuptime))) {
 
 
 9959    int prev_weight = 0;
 
 9982        prev_weight = q->
weight ? 1 : 0;
 
10003                ast_log(
LOG_WARNING, 
"'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
 
10012    if (member_reload) {
 
10019        if (queue_reload && strcasecmp(
var->name, 
"member")) {
 
10026        if (member_reload && !strcasecmp(
var->name, 
"member")) {
 
10032    if (member_reload) {
 
10048    if (!q->
weight && prev_weight) {
 
10050    } 
else if (q->
weight && !prev_weight) {
 
10055    if (member_reload) {
 
 
10073    char *queuename = arg;
 
 
10083    char *queuename = arg;
 
 
10112        ast_log(
LOG_NOTICE, 
"No call queueing config file (queues.conf), so no call queues\n");
 
10117        ast_log(
LOG_ERROR, 
"Config file queues.conf is in an invalid format.  Aborting.\n");
 
10131        if (!strcasecmp(cat, 
"general") && queue_reload) {
 
10140    if (queue_reload) {
 
 
10224    time_t now = time(
NULL);
 
10241    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",
 
10311                (
long) (
now - 
qe->start) % 60, 
qe->prio);
 
 
10335    if (argc != 2 && argc != 3) {
 
10358            char *category = 
NULL;
 
10378    if (!sorted_queues) {
 
10402            if (!realtime_queue) {
 
10407            queue_t_unref(realtime_queue, 
"Queue is already in memory");
 
 
10439    int list_len, word_len = strlen(
word);
 
10440    const char *find, *end_find, *end_list;
 
10443    while(isspace(*
list)) {
 
10447    while((find = strstr(
list, 
word))) {
 
10449        if (find != 
list && *(find - 1) != 
' ') {
 
10452            while(!isspace(*
list) && *
list != 
'\0') {
 
10456            while(isspace(*
list)) {
 
10463        list_len = strlen(
list);
 
10464        end_find = find + word_len;
 
10465        end_list = 
list + list_len;
 
10466        if (end_find == end_list || *end_find != 
' ') {
 
10469            while(!isspace(*
list) && *
list != 
'\0') {
 
10473            while(isspace(*
list)) {
 
 
10502    int wordlen = strlen(
word);
 
10504    const char *word_list = 
NULL;
 
10508    if (word_list_offset && strlen(line) >= word_list_offset) {
 
10509        word_list = line + word_list_offset;
 
10514        if (!strncasecmp(
word, q->
name, wordlen) && ++which > 
state 
10515            && (!word_list_offset || !word_list || !
word_in_list(word_list, q->
name))) {
 
10527    if (!ret && which == 
state && !wordlen && !strncmp(
"queue show", line, 10)) {
 
 
10548            "Usage: queue show\n" 
10549            "       Provides summary information on a specified queue.\n";
 
 
10599    int qchancount = 0;
 
10600    int qlongestholdtime = 0;
 
10601    int qsummaries = 0;
 
10619        snprintf(idText, 
sizeof(idText), 
"ActionID: %s\r\n", 
id);
 
10631            qlongestholdtime = 0;
 
10645            for (qe = q->
head; qe; qe = qe->
next) {
 
10646                if ((now - qe->
start) > qlongestholdtime) {
 
10647                    qlongestholdtime = now - qe->
start;
 
10654                "Available: %d\r\n" 
10658                "LongestHoldTime: %d\r\n" 
10661                q->
name, qmemcount, qmemavail, qchancount, q->
holdtime, q->
talktime, qlongestholdtime, idText);
 
 
10701        snprintf(idText, 
sizeof(idText), 
"ActionID: %s\r\n", 
id);
 
10720                "Completed: %d\r\n" 
10721                "Abandoned: %d\r\n" 
10722                "ServiceLevel: %d\r\n" 
10723                "ServicelevelPerf: %2.1f\r\n" 
10724                "ServicelevelPerf2: %2.1f\r\n" 
10740                        "StateInterface: %s\r\n" 
10741                        "Membership: %s\r\n" 
10743                        "CallsTaken: %d\r\n" 
10745                        "LastPause: %d\r\n" 
10746                        "LoginTime: %d\r\n" 
10750                        "PausedReason: %s\r\n" 
10751                        "Wrapuptime: %d\r\n" 
10765            for (qe = q->
head; qe; qe = qe->
next) {
 
10771                    "CallerIDNum: %s\r\n" 
10772                    "CallerIDName: %s\r\n" 
10773                    "ConnectedLineNum: %s\r\n" 
10774                    "ConnectedLineName: %s\r\n" 
10784                    (
long) (now - qe->
start), qe->
prio, idText);
 
 
10801    const char *queuename, *interface, *penalty_s, *paused_s, *reason, *membername, *state_interface, *wrapuptime_s;
 
10802    int paused, penalty, wrapuptime = 0;
 
10825    } 
else if (sscanf(penalty_s, 
"%30d", &penalty) != 1 || penalty < 0) {
 
10831    } 
else if (sscanf(wrapuptime_s, 
"%30d", &wrapuptime) != 1 || wrapuptime < 0) {
 
10844            ast_queue_log(queuename, 
"MANAGER", interface, 
"ADDMEMBER", 
"%s", paused ? 
"PAUSED" : 
"");
 
10846            ast_queue_log(queuename, 
"MANAGER", membername, 
"ADDMEMBER", 
"%s", paused ? 
"PAUSED" : 
"");
 
 
10866    const char *queuename, *interface;
 
10884            ast_queue_log(queuename, 
"MANAGER", interface, 
"REMOVEMEMBER", 
"%s", 
"");
 
10894        astman_send_error(s, m, 
"Unable to remove interface from queue: No such queue");
 
 
10913    const char *queuename, *interface, *paused_s, *reason;
 
10931        astman_send_ack(s, m, paused ? 
"Interface paused successfully" : 
"Interface unpaused successfully");
 
 
10938    const char *queuename, *
event, *
message, *interface, *uniqueid;
 
 
10960    const char *queuename = 
NULL;
 
10961    int header_found = 0;
 
10977    if (!header_found) {
 
 
10991    const char *queuename = 
NULL;
 
 
11020                sprintf(num, 
"%d", 
state);
 
 
11037    const char *queuename, *interface, *ringinuse_s;
 
11056        astman_send_error(s, m, 
"'RingInUse' parameter must be a truth value (yes/no, on/off, 0/1, etc)");
 
 
11071    const char *queuename, *interface, *penalty_s;
 
11084    penalty = atoi(penalty_s);
 
 
11097    const char *queuename, *caller, *priority_s, *immediate_s;
 
11118    } 
else if (sscanf(priority_s, 
"%30d", &
priority) != 1) {
 
11124        immediate = 
ast_true(immediate_s);
 
11132        astman_send_error(s, m, 
"Unable to change priority caller on queue: No such queue");
 
11135        astman_send_error(s, m, 
"Unable to change priority caller on queue: No such caller");
 
 
11144    const char *queuename, *caller, *withdraw_info;
 
11165        astman_send_error(s, m, 
"Unable to request withdraw from queue: No such queue");
 
11168        astman_send_error(s, m, 
"Unable to request withdraw from queue: No such caller");
 
11171        astman_send_error(s, m, 
"Unable to request withdraw from queue: Already requested");
 
 
11181    const char *queuename, *interface, *membername = 
NULL, *state_interface = 
NULL, *reason = 
NULL;
 
11182    int penalty, paused = 0;
 
11186        e->
command = 
"queue add member";
 
11188            "Usage: queue add member <dial string> to <queue> [penalty <penalty> [as <membername> [state_interface <interface> [paused <reason>]]]]\n" 
11189            "       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";
 
11195    if ((
a->argc != 6) && (
a->argc != 8) && (
a->argc != 10) && (
a->argc != 12) && (
a->argc != 14)) {
 
11197    } 
else if (strcmp(
a->argv[4], 
"to")) {
 
11199    } 
else if ((
a->argc >= 8) && strcmp(
a->argv[6], 
"penalty")) {
 
11201    } 
else if ((
a->argc >= 10) && strcmp(
a->argv[8], 
"as")) {
 
11203    } 
else if ((
a->argc == 12) && strcmp(
a->argv[10], 
"state_interface")) {
 
11205    } 
else if ((
a->argc == 14) && strcmp(
a->argv[12], 
"paused")) {
 
11209    queuename = 
a->argv[5];
 
11210    interface = 
a->argv[3];
 
11211    if (
a->argc >= 8) {
 
11212        if (sscanf(
a->argv[7], 
"%30d", &penalty) == 1) {
 
11214                ast_cli(
a->fd, 
"Penalty must be >= 0\n");
 
11218            ast_cli(
a->fd, 
"Penalty must be an integer >= 0\n");
 
11225    if (
a->argc >= 10) {
 
11226        membername = 
a->argv[9];
 
11229    if (
a->argc >= 12) {
 
11230        state_interface = 
a->argv[11];
 
11233    if (
a->argc >= 14) {
 
11235        reason = 
a->argv[13];
 
11241            ast_queue_log(queuename, 
"CLI", interface, 
"ADDMEMBER", 
"%s", paused ? 
"PAUSED" : 
"");
 
11243            ast_queue_log(queuename, 
"CLI", membername, 
"ADDMEMBER", 
"%s", paused ? 
"PAUSED" : 
"");
 
11245        ast_cli(
a->fd, 
"Added interface '%s' to queue '%s'\n", interface, queuename);
 
11248        ast_cli(
a->fd, 
"Unable to add interface '%s' to queue '%s': Already there\n", interface, queuename);
 
11251        ast_cli(
a->fd, 
"Unable to add interface to queue '%s': No such queue\n", queuename);
 
11254        ast_cli(
a->fd, 
"Out of memory\n");
 
11257        ast_cli(
a->fd, 
"Member not dynamic\n");
 
 
11271    int wordlen = strlen(
word);
 
11274    if (pos > 5 || pos < 3) {
 
11297                queue_t_unref(q, 
"Done with iterator, returning interface name");
 
 
11314    const char *queuename, *interface;
 
11320        e->
command = 
"queue remove member";
 
11322            "Usage: queue remove member <channel> from <queue>\n" 
11323            "       Remove a specific channel from a queue.\n";
 
11329    if (
a->argc != 6) {
 
11331    } 
else if (strcmp(
a->argv[4], 
"from")) {
 
11335    queuename = 
a->argv[5];
 
11336    interface = 
a->argv[3];
 
11345            ast_queue_log(queuename, 
"CLI", interface, 
"REMOVEMEMBER", 
"%s", 
"");
 
11349        ast_cli(
a->fd, 
"Removed interface %s from queue '%s'\n", interface, queuename);
 
11353        ast_cli(
a->fd, 
"Unable to remove interface '%s' from queue '%s': Not there\n", interface, queuename);
 
11356        ast_cli(
a->fd, 
"Unable to remove interface from queue '%s': No such queue\n", queuename);
 
11359        ast_cli(
a->fd, 
"Out of memory\n");
 
11362        ast_cli(
a->fd, 
"Unable to remove interface '%s' from queue '%s': Member is not dynamic\n", interface, queuename);
 
 
11377    const char *queuename, *caller;
 
11383        e->
command = 
"queue priority caller";
 
11385            "Usage: queue priority caller <channel> on <queue> to <priority> [immediate]\n" 
11386            "       Change the priority of a channel on a queue, optionally applying the change in relation to existing callers.\n";
 
11394    } 
else if (strcmp(
a->argv[4], 
"on")) {
 
11396    } 
else if (strcmp(
a->argv[6], 
"to")) {
 
11398    } 
else if (sscanf(
a->argv[7], 
"%30d", &
priority) != 1) {
 
11401    } 
else if (
a->argc == 9) {
 
11402        if (strcmp(
a->argv[8], 
"immediate")) {
 
11408    caller = 
a->argv[3];
 
11409    queuename = 
a->argv[5];
 
11416        ast_cli(
a->fd, 
"Unable change priority caller %s on queue '%s': No such queue\n", caller, queuename);
 
11419        ast_cli(
a->fd, 
"Unable to change priority caller '%s' on queue '%s': Not there\n", caller, queuename);
 
 
11450    const char *queuename, *interface, *reason;
 
11455        e->
command = 
"queue {pause|unpause} member";
 
11457            "Usage: queue {pause|unpause} member <member> [queue <queue> [reason <reason>]]\n" 
11458            "   Pause or unpause a queue member. Not specifying a particular queue\n" 
11459            "   will pause or unpause a member across all queues to which the member\n" 
11466    if (
a->argc < 4 || 
a->argc == 5 || 
a->argc == 7 || 
a->argc > 8) {
 
11468    } 
else if (
a->argc >= 5 && strcmp(
a->argv[4], 
"queue")) {
 
11470    } 
else if (
a->argc == 8 && strcmp(
a->argv[6], 
"reason")) {
 
11475    interface = 
a->argv[3];
 
11476    queuename = 
a->argc >= 6 ? 
a->argv[5] : 
NULL;
 
11477    reason = 
a->argc == 8 ? 
a->argv[7] : 
NULL;
 
11478    paused = !strcasecmp(
a->argv[1], 
"pause");
 
11481        ast_cli(
a->fd, 
"%spaused interface '%s'", paused ? 
"" : 
"un", interface);
 
11483            ast_cli(
a->fd, 
" in queue '%s'", queuename);
 
11486            ast_cli(
a->fd, 
" for reason '%s'", reason);
 
11491        ast_cli(
a->fd, 
"Unable to %spause interface '%s'", paused ? 
"" : 
"un", interface);
 
11493            ast_cli(
a->fd, 
" in queue '%s'", queuename);
 
11496            ast_cli(
a->fd, 
" for reason '%s'", reason);
 
 
11528    const char *queuename = 
NULL, *interface;
 
11533        e->
command = 
"queue set ringinuse";
 
11535        "Usage: queue set ringinuse <yes/no> on <interface> [in <queue>]\n" 
11536        "   Set a member's ringinuse in the queue specified. If no queue is specified\n" 
11537        "   then that interface's penalty is set in all queues to which that interface is a member.\n";
 
11545    if (
a->argc != 6 && 
a->argc != 8) {
 
11550    if (strcmp(
a->argv[4], 
"on") || (
a->argc > 6 && strcmp(
a->argv[6], 
"in"))) {
 
11555    if (
a->argc == 8) {
 
11556        queuename = 
a->argv[7];
 
11560    interface = 
a->argv[5];
 
11573        ast_cli(
a->fd, 
"Set ringinuse on interface '%s' from queue '%s'\n", interface, queuename);
 
11576        ast_cli(
a->fd, 
"Failed to set ringinuse on interface '%s' from queue '%s'\n", interface, queuename);
 
 
11585    const char *queuename = 
NULL, *interface;
 
11590        e->
command = 
"queue set penalty";
 
11592        "Usage: queue set penalty <penalty> on <interface> [in <queue>]\n" 
11593        "   Set a member's penalty in the queue specified. If no queue is specified\n" 
11594        "   then that interface's penalty is set in all queues to which that interface is a member\n";
 
11600    if (
a->argc != 6 && 
a->argc != 8) {
 
11602    } 
else if (strcmp(
a->argv[4], 
"on") || (
a->argc > 6 && strcmp(
a->argv[6], 
"in"))) {
 
11606    if (
a->argc == 8) {
 
11607        queuename = 
a->argv[7];
 
11609    interface = 
a->argv[5];
 
11610    penalty = atoi(
a->argv[3]);
 
11614        ast_cli(
a->fd, 
"Set penalty on interface '%s' from queue '%s'\n", interface, queuename);
 
11617        ast_cli(
a->fd, 
"Failed to set penalty on interface '%s' from queue '%s'\n", interface, queuename);
 
 
11628    int wordlen = strlen(
word);
 
11636        if (!strncasecmp(
word, rl_iter->
name, wordlen) && ++which > 
state) {
 
 
11653        e->
command = 
"queue show rules";
 
11655        "Usage: queue show rules [rulename]\n" 
11656        "   Show the list of rules associated with rulename. If no\n" 
11657        "   rulename is specified, list all rules defined in queuerules.conf\n";
 
11663    if (
a->argc != 3 && 
a->argc != 4) {
 
11667    rule = 
a->argc == 4 ? 
a->argv[3] : 
"";
 
11673                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);
 
 
11688            e->
command = 
"queue reset stats";
 
11690                "Usage: queue reset stats [<queuenames>]\n" 
11692                "Issuing this command will reset statistics for\n" 
11693                "<queuenames>, or for all queues if no queue is\n" 
11708    if (
a->argc == 3) {
 
11713    for (i = 3; i < 
a->argc; ++i) {
 
 
11727            e->
command = 
"queue reload {parameters|members|rules|all}";
 
11729                "Usage: queue reload {parameters|members|rules|all} [<queuenames>]\n" 
11730                "Reload queues. If <queuenames> are specified, only reload information pertaining\n" 
11731                "to <queuenames>. One of 'parameters,' 'members,' 'rules,' or 'all' must be\n" 
11732                "specified in order to know what information to reload. Below is an explanation\n" 
11733                "of each of these qualifiers.\n" 
11735                "\t'members' - reload queue members from queues.conf\n" 
11736                "\t'parameters' - reload all queue options except for queue members\n" 
11737                "\t'rules' - reload the queuerules.conf file\n" 
11738                "\t'all' - reload queue rules, parameters, and members\n" 
11740                "Note: the 'rules' qualifier here cannot actually be applied to a specific queue.\n" 
11741                "Use of the 'rules' qualifier causes queuerules.conf to be reloaded. Even if only\n" 
11742                "one queue is specified when using this command, reloading queue rules may cause\n" 
11743                "other queues to be affected\n";
 
11748                const char *command_end = 
a->line + strlen(
"queue reload ");
 
11749                command_end = strchr(command_end, 
' ');
 
11750                if (!command_end) {
 
11751                    command_end = 
a->line + strlen(
a->line);
 
11762    if (!strcasecmp(
a->argv[2], 
"rules")) {
 
11764    } 
else if (!strcasecmp(
a->argv[2], 
"members")) {
 
11766    } 
else if (!strcasecmp(
a->argv[2], 
"parameters")) {
 
11768    } 
else if (!strcasecmp(
a->argv[2], 
"all")) {
 
11772    if (
a->argc == 3) {
 
11777    for (i = 3; i < 
a->argc; ++i) {
 
 
11793    int newtalktime = 0;
 
11804        ast_log(
LOG_WARNING, 
"QueueUpdate requires arguments (queuename,uniqueid,agent,status,talktime,params[totaltime,callednumber])\n");
 
11813        ast_log(
LOG_WARNING, 
"Missing argument to QueueUpdate (queuename,uniqueid,agent,status,talktime,params[totaltime|callednumber])\n");
 
11818        newtalktime = atoi(
args.talktime);
 
11832                if (!strcasecmp(
args.status, 
"ANSWER")) {
 
11834                    q->
talktime = (((oldtalktime << 2) - oldtalktime) + newtalktime) >> 2;
 
11840                    if (newtalktime <= q->servicelevel) {
 
 
11982    ast_realtime_require_field(
"queue_members", 
"paused", 
RQ_INTEGER1, 1, 
"uniqueid", 
RQ_UINTEGER2, 5, 
"reason_paused", 
RQ_CHAR, 80, 
SENTINEL);
 
11991    if (!member_config) {
 
11994        const char *config_val;
 
11997            ast_log(
LOG_NOTICE, 
"ringinuse field entries found in queue_members table. Using 'ringinuse'\n");
 
12000            ast_log(
LOG_NOTICE, 
"ignorebusy field found in queue_members table with no ringinuse field. Using 'ignorebusy'\n");
 
12003            ast_log(
LOG_NOTICE, 
"No entries were found for ringinuse/ignorebusy in queue_members table. Using 'ringinuse'\n");
 
 
void ast_cli_unregister_multiple(void)
Generic Advice of Charge encode and decode routines.
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
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
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
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
static struct ast_custom_function queuevar_function
static void handle_bridge_enter(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
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 member_remove_from_queue(struct call_queue *queue, struct member *mem)
static int is_longest_waiting_caller(struct queue_ent *caller, struct member *member)
static void load_realtime_queues(const char *queuename)
static struct member * interface_exists(struct call_queue *q, const char *interface)
static int is_our_turn(struct queue_ent *qe)
Check if we should start attempting to call queue members.
static void record_abandoned(struct queue_ent *qe)
Record that a caller gave up on waiting in queue.
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.
static char * queue_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int get_wrapuptime(struct call_queue *q, struct member *member)
Return wrapuptime.
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.
static int context_included(const char *parent, const char *child)
Returns if one context includes another context.
static void set_queue_variables(struct call_queue *q, struct ast_channel *chan)
Set variables of queue.
static int manager_queue_reset(struct mansession *s, const struct message *m)
static struct ast_manager_event_blob * queue_member_ringinuse_to_ami(struct stasis_message *message)
static struct ast_manager_event_blob * queue_member_penalty_to_ami(struct stasis_message *message)
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 ANNOUNCEPOSITION_MORE_THAN
static int pending_members_cmp(void *obj, void *arg, int flags)
static void queue_reset_global_params(void)
static int log_caller_id_name
queues.conf [general] option
static char * complete_queue_rule_show(const char *line, const char *word, int pos, int state)
static void dump_queue_members(struct call_queue *pm_queue)
Dump all members in a specific queue to the database.
#define QUEUE_UNPAUSED_DEVSTATE
static struct ast_custom_function queuemembercount_function
static struct ast_custom_function queuewaitingcount_function
static int play_file(struct ast_channel *chan, const char *filename)
static int queue_persistent_members
queues.conf [general] option
static int montype_default
queues.conf [general] option
static int mark_member_dead(void *obj, void *arg, int flags)
static struct ast_custom_function queuememberlist_function
static struct ast_manager_event_blob * queue_channel_to_ami(const char *type, struct stasis_message *message)
static void set_queue_member_ringinuse(struct call_queue *q, struct member *mem, int ringinuse)
static char * realtime_ringinuse_field
name of the ringinuse field in the realtime database
static void queue_bridge_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static int remove_from_queue(const char *queuename, const char *interface)
Remove member from queue.
static int manager_add_queue_member(struct mansession *s, const struct message *m)
#define MAX_PERIODIC_ANNOUNCEMENTS
static void parse_empty_options(const char *value, enum empty_conditions *empty, int joinempty)
static int aqm_exec(struct ast_channel *chan, const char *data)
AddQueueMember application.
static void set_queue_result(struct ast_channel *chan, enum queue_result res)
sets the QUEUESTATUS channel variable
static struct ast_manager_event_blob * queue_member_pause_to_ami(struct stasis_message *message)
static void leave_queue(struct queue_ent *qe)
Caller leaving queue.
#define MAX_QUEUE_BUCKETS
static int reload_handler(int reload, struct ast_flags *mask, const char *queuename)
The command center for all reload operations.
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.
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.
static char * complete_queue_pause_member(const char *line, const char *word, int pos, int state)
static void do_hang(struct callattempt *o)
common hangup actions
static int set_member_value(const char *queuename, const char *interface, int property, int value)
static void reload_single_member(const char *memberdata, struct call_queue *q)
reload information pertaining to a single member
static struct ast_manager_event_blob * queue_agent_ringnoanswer_to_ami(struct stasis_message *message)
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.
static int reload_queues(int reload, struct ast_flags *mask, const char *queuename)
reload the queues.conf file
static int say_periodic_announcement(struct queue_ent *qe, int ringing)
Playback announcement to queued members if period has elapsed.
static void reload_single_queue(struct ast_config *cfg, struct ast_flags *mask, const char *queuename)
Reload information pertaining to a particular queue.
static void setup_mixmonitor(struct queue_ent *qe, const char *filename)
static struct ast_manager_event_blob * queue_member_removed_to_ami(struct stasis_message *message)
static int upqm_exec(struct ast_channel *chan, const char *data)
UnpauseQueueMember application.
static void clear_queue(struct call_queue *q)
static void handle_attended_transfer(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
Handle an attended transfer event.
static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
static int compare_weight(struct call_queue *rq, struct member *member)
static char * handle_queue_pause_member(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)
static void queue_agent_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
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.
static void queue_set_global_params(struct ast_config *cfg)
static void reload_queue_members(void)
Reload dynamic queue members persisted into the astdb.
static int rqm_exec(struct ast_channel *chan, const char *data)
RemoveQueueMember application.
static int valid_exit(struct queue_ent *qe, char digit)
Check for valid exit from queue via goto.
static int is_member_available(struct call_queue *q, struct member *mem)
#define QUEUE_PAUSED_DEVSTATE
#define ANNOUNCEPOSITION_NO
static char * handle_queue_set_member_penalty(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)
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.
static void print_queue(struct mansession *s, int fd, struct call_queue *q)
Print a single queue to AMI or the CLI.
#define MAX_CALL_ATTEMPT_BUCKETS
static void copy_rules(struct queue_ent *qe, const char *rulename)
Copy rule from global list into specified queue.
static int manager_queue_rule_show(struct mansession *s, const struct message *m)
static const struct strategy strategies[]
static int request_withdraw_caller_from_queue(const char *queuename, const char *caller, const char *withdraw_info)
Request to withdraw a caller from a queue.
static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused)
static int change_priority_caller_on_queue(const char *queuename, const char *caller, int priority, int immediate)
Change priority caller into a queue.
static struct ao2_container * queues
static int negative_penalty_invalid
queues.conf [general] option
static int load_realtime_rules(void)
Load queue rules from realtime.
static void queue_rules_reset_global_params(void)
static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl, time_t starttime)
update the queue status
static void escape_and_substitute(struct ast_channel *chan, const char *input, char *output, size_t size)
static int member_hash_fn(const void *obj, const int flags)
static int member_cmp_fn(void *obj1, void *obj2, int flags)
#define queues_t_unlink(c, q, tag)
#define DEFAULT_MIN_ANNOUNCE_FREQUENCY
The minimum number of seconds between position announcements.
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.
static void queue_stasis_data_destructor(void *obj)
static struct ast_manager_event_blob * queue_member_added_to_ami(struct stasis_message *message)
static struct ast_manager_event_blob * queue_agent_dump_to_ami(struct stasis_message *message)
static int extensionstate2devicestate(int state)
Helper function which converts from extension state to device state values.
#define queues_t_link(c, q, tag)
static int extension_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
static int manager_queue_reload(struct mansession *s, const struct message *m)
static int get_member_penalty(char *queuename, char *interface)
Gets members penalty.
static int realtime_rules
queuerules.conf [general] option
static void handle_local_optimization_begin(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static int pqm_exec(struct ast_channel *chan, const char *data)
PauseQueueMember application.
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.
static int get_member_status(struct call_queue *q, int max_penalty, int min_penalty, int raise_penalty, enum empty_conditions conditions, int devstate, int raise_respect_min)
Check if members are available.
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.
static char * handle_queue_reset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int qupd_exec(struct ast_channel *chan, const char *data)
Update Queue with data of an outgoing call.
static char * complete_queue_show(const char *line, const char *word, int pos, int state)
static char * handle_queue_set_member_ringinuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 reload_queue_rules(int reload)
Reload the rules defined in queuerules.conf.
static char * complete_queue_add_member(const char *line, const char *word, int pos, int state)
static char * handle_queue_change_priority_caller(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_queue_rule_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int manager_queue_member_ringinuse(struct mansession *s, const struct message *m)
static char * complete_queue_set_member_value(const char *line, const char *word, int pos, int state)
static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
static const char * int2strat(int strategy)
static void free_members(struct call_queue *q, int all)
Iterate through queue's member list and delete them.
static int publish_queue_member_pause(struct call_queue *q, struct member *member)
static void callattempt_free(struct callattempt *doomed)
static int store_next_lin(struct queue_ent *qe, struct callattempt *outgoing)
Search for best metric and add to Linear queue.
#define queue_t_unref(q, tag)
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 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.
#define ANNOUNCEHOLDTIME_ALWAYS
static const struct ast_app_option queue_exec_options[128]
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 int shared_lastcall
queues.conf [general] option
static int manager_queue_member_penalty(struct mansession *s, const struct message *m)
#define queue_t_ref(q, tag)
static char * __queues_show(struct mansession *s, int fd, int argc, const char *const *argv)
Show queue(s) status and statistics.
static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
Configure a queue parameter.
#define ANNOUNCEPOSITION_LIMIT
static int clear_stats(const char *queuename)
Facilitates resetting statistics for a queue.
static struct ast_custom_function queuememberpenalty_function
static void set_queue_member_pause(struct call_queue *q, struct member *mem, const char *reason, int paused)
static int queue_cmp_cb(void *obj, void *arg, int flags)
static int manager_request_withdraw_caller_from_queue(struct mansession *s, const struct message *m)
static int log_unpause_on_reason_change
queues.conf [general] option
static int set_member_value_help_members(struct call_queue *q, const char *interface, int property, int value)
static int queue_hash_cb(const void *obj, const int flags)
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.
static const char *const pm_family
Persistent Members astdb family.
static int log_membername_as_agent
queues.conf [general] option
static void update_qe_rule(struct queue_ent *qe)
update rules for queues
static void update_connected_line_from_peer(struct ast_channel *chan, struct ast_channel *peer, int is_caller)
static struct ast_manager_event_blob * queue_agent_called_to_ami(struct stasis_message *message)
static int queue_exec(struct ast_channel *chan, const char *data)
The starting point for all queue calls.
static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason, int position)
static char * handle_queue_remove_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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.
static const struct ast_app_option aqm_opts[128]
static void destroy_queue_member_cb(void *obj)
static void init_queue(struct call_queue *q)
Initialize Queue default values.
static struct ao2_container * pending_members
static struct ast_manager_event_blob * queue_multi_channel_to_ami(const char *type, struct stasis_message *message)
static struct member * find_member_by_queuename_and_interface(const char *queuename, const char *interface)
Find a member by looking up queuename and interface.
static int force_longest_waiting_caller
queues.conf [general] option
static struct ast_manager_event_blob * queue_member_status_to_ami(struct stasis_message *message)
static int kill_dead_members(void *obj, void *arg, int flags)
static void remove_stasis_subscriptions(struct queue_stasis_data *queue_data)
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.
static int pending_members_hash(const void *obj, const int flags)
static int autofill_default
queues.conf [general] option
static int manager_pause_queue_member(struct mansession *s, const struct message *m)
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'.
#define ANNOUNCEHOLDTIME_ONCE
static struct ast_manager_event_blob * queue_caller_join_to_ami(struct stasis_message *message)
static int queue_delme_members_decrement_followers(void *obj, void *arg, int flag)
static int insert_penaltychange(const char *list_name, const char *content, const int linenum)
Change queue penalty by adding rule.
static char * handle_queue_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int num_available_members(struct call_queue *q)
Get the number of members available to accept a call.
static int ql_exec(struct ast_channel *chan, const char *data)
QueueLog application.
static int manager_remove_queue_member(struct mansession *s, const struct message *m)
static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
static int store_next_rr(struct queue_ent *qe, struct callattempt *outgoing)
Search for best metric and add to Round Robbin queue.
static struct stasis_message_router * agent_router
static void queue_member_follower_removal(struct call_queue *queue, struct member *mem)
static struct member * get_interface_helper(struct call_queue *q, const char *interface)
static int mark_unfound(void *obj, void *arg, int flags)
@ QUEUE_RELOAD_PARAMETERS
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
static int load_module(void)
Load the module.
static void member_add_to_queue(struct call_queue *queue, struct member *mem)
static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
Part 2 of ring_one.
static void pending_members_remove(struct member *mem)
static void end_bridge_callback(void *data)
static struct stasis_subscription * device_state_sub
Subscription to device state change messages.
static int manager_queues_summary(struct mansession *s, const struct message *m)
Summary of queue info via the AMI.
static struct call_queue * alloc_queue(const char *queuename)
static struct callattempt * find_best(struct callattempt *outgoing)
find the entry with the best metric, or NULL
static int get_queue_member_status(struct member *cur)
Return the current state of a member.
static int unload_module(void)
#define QUEUE_UNKNOWN_PAUSED_DEVSTATE
static void publish_dial_end_event(struct ast_channel *in, struct callattempt *outgoing, struct ast_channel *exception, const char *status)
static int manager_queues_status(struct mansession *s, const struct message *m)
Queue status info via AMI.
static void handle_local_optimization_end(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static int say_position(struct queue_ent *qe, int ringing)
static int realtime_reason_paused
does realtime backend support reason_paused
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)
static void update_realtime_members(struct call_queue *q)
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.
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 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.
static struct ast_manager_event_blob * queue_agent_connect_to_ami(struct stasis_message *message)
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
@ QUEUE_EMPTY_UNAVAILABLE
static struct ast_json * queue_member_blob_create(struct call_queue *q, struct member *mem)
static void queue_channel_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static int use_weight
Records that one or more queues use weight.
#define ANNOUNCEPOSITION_YES
static int wait_a_bit(struct queue_ent *qe)
static void destroy_queue(void *obj)
Free queue's member list then its string fields.
static int kill_if_unfound(void *obj, void *arg, int flags)
static void handle_hangup(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static void do_print(struct mansession *s, int fd, const char *str)
direct output to manager or cli with proper terminator
static char * complete_queue_remove_member(const char *line, const char *word, int pos, int state)
static char * handle_queue_add_member(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 void queue_rules_set_global_params(struct ast_config *cfg)
static int member_status_available(int status)
static int queue_member_decrement_followers(void *obj, void *arg, int flag)
static struct ast_cli_entry cli_queue[]
@ OPT_ARG_MUSICONHOLD_CLASS
static struct call_queue * find_load_queue_rt_friendly(const char *queuename)
static struct ast_custom_function queuegetchannel_function
static struct ast_manager_event_blob * queue_caller_abandon_to_ami(struct stasis_message *message)
static struct stasis_forward * topic_forwarder
static struct ast_custom_function queueexists_function
@ AQM_OPT_ARG_PAUSE_REASON
static int strat2int(const char *strategy)
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 struct ast_manager_event_blob * queue_agent_complete_to_ami(struct stasis_message *message)
static void setup_peer_after_bridge_goto(struct ast_channel *chan, struct ast_channel *peer, struct ast_flags *opts, char *opt_args[])
static int word_in_list(const char *list, const char *word)
Check if a given word is in a space-delimited list.
static void log_attended_transfer(struct queue_stasis_data *queue_data, struct ast_attended_transfer_message *atxfer_msg)
static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
Place a call to a queue member.
@ OPT_IGNORE_CONNECTEDLINE
static const struct @51 queue_results[]
static void handle_blind_transfer(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
Handle a blind transfer event.
static const struct autopause autopausesmodes[]
static struct ast_manager_event_blob * queue_member_to_ami(const char *type, struct stasis_message *message)
@ QUEUE_STRATEGY_RRMEMORY
@ QUEUE_STRATEGY_LEASTRECENT
@ QUEUE_STRATEGY_FEWESTCALLS
@ QUEUE_STRATEGY_RRORDERED
static int autopause2int(const char *autopause)
static int manager_change_priority_caller_on_queue(struct mansession *s, const struct message *m)
static int compress_char(const char c)
static void queue_publish_member_blob(struct stasis_message_type *type, struct ast_json *blob)
static int manager_queue_log_custom(struct mansession *s, const struct message *m)
static struct ast_manager_event_blob * queue_caller_leave_to_ami(struct stasis_message *message)
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 *gosub, int ringing)
static int set_member_penalty_help_members(struct call_queue *q, const char *interface, int penalty)
Persistent data storage (akin to *doze registry)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
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.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
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_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_t_iterator_next(iter, tag)
#define ao2_t_find(container, arg, flags, tag)
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_unlink(container, obj)
Remove an object from a container.
@ AO2_ITERATOR_DONTLOCK
Assume that the ao2_container is already locked.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define AO2_STRING_FIELD_SORT_FN(stype, field)
Creates a sort function for a structure string field.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
@ AST_BRIDGE_TRANSFER_SUCCESS
After Bridge Execution API.
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.
static void ringing(struct ast_channel *chan)
Helper method to send a ringing indication to a channel in a bridge.
Basic bridge subclass API.
#define AST_TRANSFERER_ROLE_NAME
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
int ast_channel_has_role(struct ast_channel *channel, const char *role_name)
Check if a role exists on a channel.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
#define AST_PRES_RESTRICTION
Internal Asterisk hangup causes.
#define AST_CAUSE_ANSWERED_ELSEWHERE
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
static int call(void *data)
General Asterisk PBX channel definitions.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
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.
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
@ AST_CHANNEL_REQUESTOR_BRIDGE_PEER
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
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...
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...
#define ast_channel_lock(chan)
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
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.
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.
int ast_channel_priority(const struct ast_channel *chan)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
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().
const char * ast_channel_context(const struct ast_channel *chan)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
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.
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.
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.
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.
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
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.
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
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.
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
int ast_channel_sendurl(struct ast_channel *channel, const char *url)
Sends a URL on a given link Send URL on link.
const char * ast_channel_language(const struct ast_channel *chan)
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
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.
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().
const char * ast_channel_call_forward(const struct ast_channel *chan)
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
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.
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
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 * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
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.
ast_channel_state
ast_channel states
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Local proxy channel special access.
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
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.
const char * ast_devstate2str(enum ast_device_state devstate) attribute_pure
Convert device state to text string for output.
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
ast_device_state
Device States.
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
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.
Generic File Format Support. Should be included by clients of the file handling routines....
int ast_stopstream(struct ast_channel *c)
Stops a stream.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
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.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
void astman_append(struct mansession *s, const char *fmt,...)
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
struct stasis_message_type * ast_channel_masquerade_type(void)
Message type for when a channel is being masqueraded.
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
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.
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.
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
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.
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,...
struct stasis_message_type * ast_channel_agent_logoff_type(void)
Message type for agent logoff on a channel.
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.
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...
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.
struct stasis_message_type * ast_channel_hangup_request_type(void)
Message type for when a hangup is requested on a channel.
struct stasis_message_type * ast_channel_agent_login_type(void)
Message type for agent login on a channel.
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.
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...
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
struct stasis_topic * ast_queue_topic(const char *queuename)
Get the Stasis Message Bus API topic for queue messages for a particular queue name.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
struct stasis_topic * ast_queue_topic_all(void)
Get the Stasis Message Bus API topic for queue messages.
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.
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.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
@ CONFIG_FLAG_FILEUNCHANGED
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
#define AST_OPTION_TONE_VERIFY
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_PVT_CAUSE_CODE
#define ast_debug(level,...)
Log a DEBUG message.
void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt,...)
#define ast_verb(level,...)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
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.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Asterisk locking-related definitions:
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
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.
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.
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
loadable MixMonitor functionality
int ast_start_mixmonitor(struct ast_channel *chan, const char *filename, const char *options)
Start a mixmonitor on a channel with the given parameters.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_DEVSTATE_CONSUMER
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Core PBX routines and definitions.
const struct ast_include * ast_walk_context_includes(const struct ast_context *con, const struct ast_include *inc)
struct ast_context * ast_context_find(const char *name)
Find a context.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
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.
const char * ast_get_include_name(const struct ast_include *include)
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,...
@ AST_EXTENSION_NOT_INUSE
@ AST_EXTENSION_UNAVAILABLE
@ AST_EXTENSION_DEACTIVATED
const char * ast_get_context_name(struct ast_context *con)
#define ast_custom_function_register(acf)
Register a custom function.
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
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.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_extension_state_del(int id, ast_state_cb_type change_cb)
Deletes a state change watcher by ID.
int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Add watcher for extension states.
struct ast_app * pbx_findapp(const char *app)
Look up an application.
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.
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
static void to_ami(struct ast_sip_subscription *sub, struct ast_str **buf)
Say numbers and dates (maybe words one day too)
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
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.
#define STASIS_MESSAGE_TYPE_DEFN_LOCAL(name,...)
Boiler-plate messaging macro for defining local message types.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a 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.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
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.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
#define stasis_subscribe(topic, callback, data)
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for ast_channel enter bridge blob messages.
struct stasis_message_type * ast_blind_transfer_type(void)
Message type for ast_blind_transfer_message.
struct stasis_message_type * ast_attended_transfer_type(void)
Message type for ast_attended_transfer_message.
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
@ AST_ATTENDED_TRANSFER_DEST_FAIL
@ AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE
@ AST_ATTENDED_TRANSFER_DEST_LOCAL_APP
@ AST_ATTENDED_TRANSFER_DEST_LINK
@ AST_ATTENDED_TRANSFER_DEST_APP
@ AST_ATTENDED_TRANSFER_DEST_THREEWAY
#define stasis_message_router_create(topic)
Create a new message router object.
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.
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.
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.
#define stasis_message_router_create_pool(topic)
Create a new message router object.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
#define ast_str_alloca(init_len)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
ast_app: A registered application
Message representing attended transfer.
enum ast_attended_transfer_dest_type dest_type
struct ast_channel_snapshot * links[2]
struct ast_bridge_channel_snapshot_pair to_transfer_target
enum ast_transfer_result result
union ast_attended_transfer_message::@305 dest
struct ast_bridge_channel_snapshot_pair to_transferee
char bridge[AST_UUID_STR_LEN]
Message published during a blind transfer.
char exten[AST_MAX_EXTENSION]
struct ast_bridge_snapshot * bridge
enum ast_transfer_result result
char context[AST_MAX_CONTEXT]
Blob of data associated with a bridge.
struct ast_bridge_snapshot * bridge
struct ast_channel_snapshot * channel
struct ast_bridge_snapshot * bridge_snapshot
void * end_bridge_callback_data
struct ast_flags features_callee
struct ast_flags features_caller
void(* end_bridge_callback)(void *)
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
const ast_string_field uniqueid
Blob of data associated with a channel.
struct ast_channel_snapshot * snapshot
const ast_string_field uniqueid
const ast_string_field name
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot_caller * caller
Structure to describe a channel "technology", ie a channel driver See for examples:
Main Channel structure associated with a channel.
const struct ast_channel_tech * tech
char context[AST_MAX_CONTEXT]
descriptor for a cli entry.
ast_context: An extension context
Data structure associated with a custom dialplan function.
struct ast_db_entry * next
The structure that contains device state.
enum ast_device_state state
const struct ast_eid * eid
The EID of the server where this message originated.
Structure used to handle boolean flags.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@239 data
ast_include: include= support in extensions.conf
Abstract JSON element (object, array, string, int, ...).
Struct containing info for an AMI event to send out.
A multi channel blob data structure for multi_channel_blob stasis messages.
Caller Party information.
struct ast_party_id id
Caller party ID.
struct ast_party_id ani
Automatic Number Identification (ANI)
Connected Line/Party information.
int source
Information about the source of an update.
struct ast_party_id id
Connected party ID.
struct ast_party_id ani
Automatic Number Identification (ANI)
char * str
Subscriber phone number (Malloced)
struct ast_party_dialed::@221 number
Dialed/Called number.
int transit_network_select
Transit Network Select.
struct ast_party_name name
Subscriber name.
struct ast_party_number number
Subscriber phone number.
unsigned char valid
TRUE if the name information is valid/present.
char * str
Subscriber name (Malloced)
unsigned char valid
TRUE if the number information is valid/present.
char * str
Subscriber phone number (Malloced)
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
unsigned int autopauseunavail
const ast_string_field sound_thereare
unsigned int setinterfacevar
struct ast_str * sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS]
const ast_string_field sound_callerannounce
const ast_string_field sound_reporthold
unsigned int announceholdtime
const ast_string_field sound_holdtime
unsigned int reportholdtime
unsigned int setqueueentryvar
const ast_string_field sound_seconds
unsigned int timeoutrestart
struct ao2_container * members
int periodicannouncefrequency
const ast_string_field sound_thanks
unsigned int announceposition_only_up
int announcepositionlimit
unsigned int announce_to_first_user
int randomperiodicannounce
int periodicannouncestartdelay
const ast_string_field defaultrule
int log_restricted_caller_id
const ast_string_field queue_quantity2
const ast_string_field moh
struct call_queue::@54 list
enum empty_conditions leavewhenempty
const ast_string_field context
const ast_string_field sound_calls
const ast_string_field sound_minute
const ast_string_field sound_minutes
unsigned int announceposition
const ast_string_field queue_quantity1
const ast_string_field membergosub
enum empty_conditions joinempty
struct call_queue::@55 rules
const ast_string_field name
const ast_string_field sound_next
unsigned int autopausebusy
const ast_string_field announce
unsigned int relativeperiodicannounce
We define a custom "local user" structure because we use it not only for keeping track of what is in ...
unsigned int dial_callerid_absent
unsigned int block_connected_update
struct ast_aoc_decoded * aoc_s_rate_list
struct ast_party_connected_line connected
struct callattempt * call_next
struct ast_channel * chan
struct callattempt * q_next
unsigned int pending_connected_update
structure to hold extensions
Structure representing relevant data during a local channel optimization.
const char * source_chan_uniqueid
In case you didn't read that giant block of text above the mansession_session struct,...
Channel datastore data for max forwards.
char interface[AST_CHANNEL_NAME]
char state_exten[AST_MAX_EXTENSION]
char state_context[AST_MAX_CONTEXT]
struct call_queue * lastqueue
char state_interface[AST_CHANNEL_NAME]
struct penalty_rule::@53 list
struct ast_channel * chan
char digits[AST_MAX_EXTENSION]
time_t last_periodic_announce_time
struct queue_ent::@52 qe_rules
struct ast_channel * chan
int cancel_answered_elsewhere
char context[AST_MAX_CONTEXT]
int last_periodic_announce_sound
const char * predial_callee
struct call_queue * parent
User data for stasis subscriptions used for queue calls.
const ast_string_field caller_uniqueid
const ast_string_field member_uniqueid
struct local_optimization member_optimize
struct stasis_message_router * channel_router
struct call_queue * queue
const ast_string_field bridge_uniqueid
struct stasis_message_router * bridge_router
struct local_optimization caller_optimize
struct rule_list::@57 list
struct rule_list::@56 rules
An API for managing task processing threads that can be shared across modules.
Handy terminal functions for vt* terms.
const char * ast_term_reset(void)
Returns the terminal reset code.
const char * ast_term_color(int fgcolor, int bgcolor)
Return a color sequence string.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Support for translation of data formats. translate.c.
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
long int ast_random(void)
#define ast_set_flag(p, flag)
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.