Index: channels/chan_skinny.c =================================================================== --- channels/chan_skinny.c (revision 367677) +++ channels/chan_skinny.c (working copy) @@ -2085,7 +2085,7 @@ AST_LIST_TRAVERSE(&devices, d, list){ struct ast_sockaddr addr; ast_sockaddr_from_sin(&addr, &s->sin); - if (!strcasecmp(req->data.reg.name, d->id) + if (!d->session && !strcasecmp(req->data.reg.name, d->id) && ast_apply_ha(d->ha, &addr)) { s->device = d; d->type = letohl(req->data.reg.type); @@ -2153,12 +2153,15 @@ struct skinny_device *d; struct skinny_line *l; struct skinny_speeddial *sd; + struct skinny_subchannel *sub; + struct ast_channel *chan; d = s->device; if (d) { d->session = NULL; d->registered = 0; + d->hookstate = SKINNY_ONHOOK; AST_LIST_TRAVERSE(&d->speeddials, sd, list) { if (sd->stateid > -1) @@ -2166,7 +2169,25 @@ } AST_LIST_TRAVERSE(&d->lines, l, list) { if (l->device == d) { + AST_LIST_TRAVERSE(&l->sub, sub, list) { + AST_LIST_REMOVE(&l->sub, sub, list); + ast_mutex_lock(&sub->lock); + if (sub->owner) { + chan = sub->owner; + sub->owner = NULL; + ast_channel_tech_pvt_set(chan, NULL); + ast_softhangup(chan, AST_SOFTHANGUP_APPUNLOAD); + } + if (sub->rtp) { + ast_rtp_instance_destroy(sub->rtp); + sub->rtp = NULL; + } + ast_mutex_unlock(&sub->lock); + ast_free(sub); + ast_module_unref(ast_module_info->self); + } l->device = NULL; + l->activesub = NULL; ast_format_cap_remove_all(l->cap); ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0); l->instance = 0;