Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 108287) +++ apps/app_queue.c (working copy) @@ -572,65 +572,32 @@ int state; char dev[0]; }; -/*! \brief set a member's status based on device state of that member's interface*/ -static void *handle_statechange(struct statechange *sc) + +static int update_status(const char *interface, const int status) { - struct call_queue *q; struct member *cur; struct ao2_iterator mem_iter; - struct member_interface *curint; - char *loc; - char *technology; + struct call_queue *q; - technology = ast_strdupa(sc->dev); - loc = strchr(technology, '/'); - if (loc) { - *loc++ = '\0'; - } else { - return NULL; - } - - AST_LIST_LOCK(&interfaces); - AST_LIST_TRAVERSE(&interfaces, curint, list) { - char *interface; - char *slash_pos; - interface = ast_strdupa(curint->interface); - if ((slash_pos = strchr(interface, '/'))) - if ((slash_pos = strchr(slash_pos + 1, '/'))) - *slash_pos = '\0'; - - if (!strcasecmp(interface, sc->dev)) - break; - } - AST_LIST_UNLOCK(&interfaces); - - if (!curint) { - 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; - } - - if (option_debug) - ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state)); AST_LIST_LOCK(&queues); AST_LIST_TRAVERSE(&queues, q, list) { ast_mutex_lock(&q->lock); mem_iter = ao2_iterator_init(q->members, 0); while ((cur = ao2_iterator_next(&mem_iter))) { - char *interface; + char *tmp_interface; char *slash_pos; - interface = ast_strdupa(cur->interface); - if ((slash_pos = strchr(interface, '/'))) + tmp_interface = ast_strdupa(cur->interface); + if ((slash_pos = strchr(tmp_interface, '/'))) if ((slash_pos = strchr(slash_pos + 1, '/'))) *slash_pos = '\0'; - if (strcasecmp(sc->dev, interface)) { + if (strcasecmp(interface, tmp_interface)) { ao2_ref(cur, -1); continue; } - if (cur->status != sc->state) { - cur->status = sc->state; + if (cur->status != status) { + cur->status = status; if (q->maskmemberstatus) { ao2_ref(cur, -1); continue; @@ -655,6 +622,49 @@ } AST_LIST_UNLOCK(&queues); + 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 member_interface *curint; + char *loc; + char *technology; + + technology = ast_strdupa(sc->dev); + loc = strchr(technology, '/'); + if (loc) { + *loc++ = '\0'; + } else { + return NULL; + } + + AST_LIST_LOCK(&interfaces); + AST_LIST_TRAVERSE(&interfaces, curint, list) { + char *interface; + char *slash_pos; + interface = ast_strdupa(curint->interface); + if ((slash_pos = strchr(interface, '/'))) + if ((slash_pos = strchr(slash_pos + 1, '/'))) + *slash_pos = '\0'; + + if (!strcasecmp(interface, sc->dev)) + break; + } + AST_LIST_UNLOCK(&interfaces); + + if (!curint) { + 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; + } + + if (option_debug) + ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state)); + + update_status(sc->dev, sc->state); + return NULL; } @@ -1685,55 +1695,7 @@ } } -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 */ - ast_mutex_lock(&q->lock); - 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); - } - ast_mutex_unlock(&q->lock); - 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); -} - /* traverse all defined queues which have calls waiting and contain this member return 0 if no other queue has precedence (higher weight) or 1 if found */ static int compare_weight(struct call_queue *rq, struct member *member) @@ -1869,16 +1831,16 @@ 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->interface, ast_device_state(tmp->member->interface)); + ast_mutex_lock(&qe->parent->lock); qe->parent->rrpos++; ast_mutex_unlock(&qe->parent->lock); (*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)"; @@ -2208,8 +2170,6 @@ ast_verbose(VERBOSE_PREFIX_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; @@ -2788,8 +2748,8 @@ else to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1; ++qe->pending; - ring_one(qe, outgoing, &numbusies); ast_mutex_unlock(&qe->parent->lock); + ring_one(qe, outgoing, &numbusies); if (use_weight) AST_LIST_UNLOCK(&queues); lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);