diff -u -r asterisk-1.4.20.1.orig/channels/chan_sip.c asterisk-1.4.20.1/channels/chan_sip.c --- asterisk-1.4.20.1.orig/channels/chan_sip.c 2008-05-14 14:51:06.000000000 +0200 +++ asterisk-1.4.20.1/channels/chan_sip.c 2008-06-17 12:20:44.000000000 +0200 @@ -3223,7 +3223,10 @@ inuse = &u->inUse; call_limit = &u->call_limit; inringing = NULL; - } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ + } + /* but if it is also a peer, we use the peer part, as we only check + * user state on users that are not peers. */ + if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ inuse = &p->inUse; call_limit = &p->call_limit; inringing = &p->inRinging; @@ -3283,8 +3286,10 @@ } } /* Continue */ - (*inuse)++; - ast_set_flag(&fup->flags[0], SIP_INC_COUNT); + if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { + (*inuse)++; + ast_set_flag(&fup->flags[0], SIP_INC_COUNT); + } if (option_debug > 1 || sipdebug) { ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); } @@ -3308,8 +3313,10 @@ if (p) { ast_device_state_changed("SIP/%s", p->name); ASTOBJ_UNREF(p, sip_destroy_peer); - } else /* u must be set */ + } else {/* u must be set */ + ast_device_state_changed("SIP/%s", u->name); ASTOBJ_UNREF(u, sip_destroy_user); + } return 0; } @@ -15991,7 +15998,8 @@ struct hostent *hp; struct ast_hostent ahp; - struct sip_peer *p; + struct sip_peer *p = NULL; + struct sip_user *u = NULL; int res = AST_DEVICE_INVALID; @@ -16027,7 +16035,7 @@ } else if (p->call_limit && (p->inUse == p->call_limit)) /* check call limit */ res = AST_DEVICE_BUSY; - else if (p->call_limit && p->inUse) + else if (p->inUse) /* Not busy, but we do have a call */ res = AST_DEVICE_INUSE; else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) @@ -16040,6 +16048,18 @@ res = AST_DEVICE_UNAVAILABLE; } ASTOBJ_UNREF(p,sip_destroy_peer); + } else if ((u = find_user(host, 1))) { + /* for a user we don't have an address, but we + * know if a call is progressing from that user. + */ + if (u->call_limit && (u->inUse == u->call_limit)) + /* check call limit */ + res = AST_DEVICE_BUSY; + else if (u->inUse) + /* Not busy, but we do have a call */ + res = AST_DEVICE_INUSE; + else /* Default reply if we're registered and have no other data */ + res = AST_DEVICE_NOT_INUSE; } else { char *port = strchr(host, ':'); if (port)