diff --git a/apps/app_queue.c b/apps/app_queue.c index ca109f9b63..b8a084491a 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -675,13 +675,62 @@ struct statechange { * Lock interface list find sc, iterate through each queues queue_member list for member to * update state inside queues */ +static int update_status(const char *interface, const int status) +{ + struct member *cur; + struct ao2_iterator mem_iter, queue_iter; + struct call_queue *q; + + queue_iter = ao2_iterator_init(queues, 0); + while ((q = ao2_iterator_next(&queue_iter))) { + ao2_lock(q); + mem_iter = ao2_iterator_init(q->members, 0); + while ((cur = ao2_iterator_next(&mem_iter))) { + char *tmp_interface; + char *slash_pos; + tmp_interface = ast_strdupa(cur->state_interface); + if ((slash_pos = strchr(interface, '/'))) + if ((slash_pos = strchr(slash_pos + 1, '/'))) + *slash_pos = '\0'; + + if (strcasecmp(interface, tmp_interface)) { + ao2_ref(cur, -1); + continue; + } + + if (cur->status != status) { + cur->status = status; + if (q->maskmemberstatus) { + ao2_ref(cur, -1); + continue; + } + + manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus", + "Queue: %s\r\n" + "Location: %s\r\n" + "MemberName: %s\r\n" + "Membership: %s\r\n" + "Penalty: %d\r\n" + "CallsTaken: %d\r\n" + "LastCall: %d\r\n" + "Status: %d\r\n" + "Paused: %d\r\n", + q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static", + cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused); + } + ao2_ref(cur, -1); + } + queue_unref(q); + ao2_unlock(q); + } + + return 0; +} + +/*! \brief set a member's status based on device state of that member's interface*/ static void *handle_statechange(struct statechange *sc) { - struct call_queue *q; - struct member *cur; - struct ao2_iterator mem_iter; struct member_interface *curint; - struct ao2_iterator queue_iter; char *loc; char *technology; @@ -708,53 +757,15 @@ static void *handle_statechange(struct statechange *sc) AST_LIST_UNLOCK(&interfaces); if (!curint) { - ast_debug(3, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state)); + if (option_debug > 2) + ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state)); return NULL; } - ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state)); - queue_iter = ao2_iterator_init(queues, 0); - while ((q = ao2_iterator_next(&queue_iter))) { - ao2_lock(q); - mem_iter = ao2_iterator_init(q->members, 0); - while ((cur = ao2_iterator_next(&mem_iter))) { - char *interface; - char *slash_pos; - interface = ast_strdupa(cur->state_interface); - if ((slash_pos = strchr(interface, '/'))) - if ((slash_pos = strchr(slash_pos + 1, '/'))) - *slash_pos = '\0'; + if (option_debug) + ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state)); - if (strcasecmp(sc->dev, interface)) { - ao2_ref(cur, -1); - continue; - } - - if (cur->status != sc->state) { - cur->status = sc->state; - if (q->maskmemberstatus) { - ao2_ref(cur, -1); - continue; - } - - manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus", - "Queue: %s\r\n" - "Location: %s\r\n" - "MemberName: %s\r\n" - "Membership: %s\r\n" - "Penalty: %d\r\n" - "CallsTaken: %d\r\n" - "LastCall: %d\r\n" - "Status: %d\r\n" - "Paused: %d\r\n", - q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static", - cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused); - } - ao2_ref(cur, -1); - } - queue_unref(q); - ao2_unlock(q); - } + update_status(sc->dev, sc->state); return NULL; } @@ -1984,55 +1995,6 @@ static void hangupcalls(struct callattempt *outgoing, struct ast_channel *except } } -static int update_status(struct call_queue *q, struct member *member, int status) -{ - struct member *cur; - struct ao2_iterator mem_iter; - - /* Since a reload could have taken place, we have to traverse the list to - be sure it's still valid */ - ao2_lock(q); - mem_iter = ao2_iterator_init(q->members, 0); - while ((cur = ao2_iterator_next(&mem_iter))) { - if (member != cur) { - ao2_ref(cur, -1); - continue; - } - - cur->status = status; - if (!q->maskmemberstatus) { - manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus", - "Queue: %s\r\n" - "Location: %s\r\n" - "MemberName: %s\r\n" - "Membership: %s\r\n" - "Penalty: %d\r\n" - "CallsTaken: %d\r\n" - "LastCall: %d\r\n" - "Status: %d\r\n" - "Paused: %d\r\n", - q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static", - cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused); - } - ao2_ref(cur, -1); - } - ao2_unlock(q); - return 0; -} - -static int update_dial_status(struct call_queue *q, struct member *member, int status) -{ - if (status == AST_CAUSE_BUSY) - status = AST_DEVICE_BUSY; - else if (status == AST_CAUSE_UNREGISTERED) - status = AST_DEVICE_UNAVAILABLE; - else if (status == AST_CAUSE_NOSUCHDRIVER) - status = AST_DEVICE_INVALID; - else - status = AST_DEVICE_UNKNOWN; - return update_status(q, member, status); -} - /*! * \brief traverse all defined queues which have calls waiting and contain this member * \retval 0 if no other queue has precedence (higher weight) @@ -2189,7 +2151,8 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies if (qe->chan->cdr) ast_cdr_busy(qe->chan->cdr); tmp->stillgoing = 0; - update_dial_status(qe->parent, tmp->member, status); + + update_status(tmp->member->state_interface, ast_device_state(tmp->member->state_interface)); ao2_lock(qe->parent); qe->parent->rrpos++; @@ -2199,8 +2162,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies (*busies)++; return 0; - } else if (status != tmp->oldstatus) - update_dial_status(qe->parent, tmp->member, status); + } tmp->chan->appl = "AppQueue"; tmp->chan->data = "(Outgoing Line)"; @@ -2567,8 +2529,6 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name); /* Setup parameters */ o->chan = ast_request(tech, in->nativeformats, stuff, &status); - if (status != o->oldstatus) - update_dial_status(qe->parent, o->member, status); if (!o->chan) { ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff); o->stillgoing = 0; @@ -3281,8 +3241,8 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1; orig = to; ++qe->pending; - ring_one(qe, outgoing, &numbusies); ao2_unlock(qe->parent); + ring_one(qe, outgoing, &numbusies); if (use_weight) ao2_unlock(queues); lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);