--- app_queue.c.orig 2014-02-26 18:04:35.903891792 +0200 +++ app_queue.c 2014-02-26 18:27:43.323145849 +0200 @@ -1919,6 +1919,25 @@ { return ast_strlen_zero(cur->state_exten) ? ast_device_state(cur->state_interface) : extensionstate2devicestate(ast_extension_state(NULL, cur->state_context, cur->state_exten)); } +/*! \brief Return if member has open channel */ +static int get_if_queue_member_has_chan(const char *interface) +{ + int state; + + state = ast_parse_device_state(interface); + if (state == AST_DEVICE_INUSE || state == AST_DEVICE_BUSY || state == AST_DEVICE_RINGING + || state == AST_DEVICE_RINGINUSE || state == AST_DEVICE_ONHOLD) + { + ast_debug(3,"Member %s has channel and it's status is %d \n", interface, state); + return 1; + }else{ + ast_verb(3,"Member %s does not have channel and it's status is %d \n", interface, state); + + return 0; + } + +} + /*! \brief allocate space for new queue member and set fields based on parameters passed */ static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface, int ringinuse) @@ -3589,7 +3608,17 @@ * because the device state and extension state callbacks may * not have updated the status yet. */ - if (!member_status_available(get_queue_member_status(call->member))) { + if (!member_status_available(get_queue_member_status(call->member)) + /* + * Seems that realtime peers after we run "sip reload" or on (lagged/unreachable) -> (reachable) change or + * lose the status, and apparently the fucntions in get_queue_member_status would + * get the new status as NOT_INUSE + * The resolution is to check in channels, but as it would get wrong status + * when extension is actually really NOT_INUSE, we will only consider statuses when we can't + * get the call :) + */ + + || (call->member->realtime && get_if_queue_member_has_chan(call->member->state_interface))) { ast_debug(1, "%s actually not available, can't receive call\n", call->interface); member_call_pending_clear(call->member);