Index: chan_sip.c
===================================================================
--- chan_sip.c	(.../vendor/1.6.1/12/channels/chan_sip.c)	(revision 2)
+++ chan_sip.c	(.../local/1.6.1/12/channels/chan_sip.c)	(revision 17)
@@ -2167,6 +2167,7 @@
 static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno);
 static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
 static void set_socket_transport(struct sip_socket *socket, int transport);
+static void unregister_peer(struct sip_peer *peer, const char* mgr_cause);
 
 /* Realtime device support */
 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, const char *useragent, int expirey, int deprecated_username, int lastms);
@@ -11180,15 +11181,14 @@
 	}
 }
 
-/*! \brief Expire registration of SIP peer */
-static int expire_register(const void *data)
+static void unregister_peer(struct sip_peer *peer, const char* mgr_cause)
 {
-	struct sip_peer *peer = (struct sip_peer *)data;
-
-	if (!peer)		/* Hmmm. We have no peer. Weird. */
-		return 0;
-
 	peer->expire = -1;
+	peer->fullcontact[0] = '\0';
+	peer->useragent[0] = '\0';
+	peer->sipoptions = 0;
+	peer->lastms = 0;
+
 	peer->portinuri = 0;
 	memset(&peer->addr, 0, sizeof(peer->addr));
 
@@ -11200,23 +11200,40 @@
 		peer->socket.tcptls_session = NULL;
 	}
 
-	manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
 	register_peer_exten(peer, FALSE);	/* Remove regexten */
 	ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
 
+	if (mgr_cause)
+		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: %s\r\n", peer->name, mgr_cause);
+	else
+		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
+
+	ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
+
 	/* Do we need to release this peer from memory? 
 		Only for realtime peers and autocreated peers
 	*/
 	if (peer->is_realtime)
 		ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
 
-	if (peer->selfdestruct ||
-	    ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
+	if (peer->selfdestruct || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
 		ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
 		if (peer->addr.sin_addr.s_addr) {
 			ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
 		}
+		ast_verb(3, "Unlinked SIP peer '%s'\n", peer->name);
 	}
+}
+
+/*! \brief Expire registration of SIP peer */
+static int expire_register(const void *data)
+{
+	struct sip_peer *peer = (struct sip_peer *)data;
+
+	if (!peer)		/* Hmmm. We have no peer. Weird. */
+		return 0;
+
+	unregister_peer(peer, "Expired");
 
 	unref_peer(peer, "removing peer ref for expire_register");
 
@@ -11427,25 +11444,10 @@
 		return PARSE_REGISTER_QUERY;
 	} else if (!strcasecmp(curi, "*") || !expire) {	/* Unregister this peer */
 		/* This means remove all registrations and return OK */
-		memset(&peer->addr, 0, sizeof(peer->addr));
-		set_socket_transport(&peer->socket, peer->default_outbound_transport);
-
-		AST_SCHED_DEL_UNREF(sched, peer->expire,
-				unref_peer(peer, "remove register expire ref"));
-
-		destroy_association(peer);
-
-		register_peer_exten(peer, FALSE);	/* Remove extension from regexten= setting in sip.conf */
-		peer->fullcontact[0] = '\0';
-		peer->useragent[0] = '\0';
-		peer->sipoptions = 0;
-		peer->lastms = 0;
+		AST_SCHED_DEL_UNREF(sched, peer->expire, unref_peer(peer, "remove register expire ref"));
+		unregister_peer(peer, NULL);
 		peer->portinuri = 0;
 		pvt->expiry = 0;
-
-		ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
-
-		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
 		return PARSE_REGISTER_UPDATE;
 	}
 
@@ -14965,12 +14967,11 @@
 	
 	if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) {
 		if (peer->expire > 0) {
-			AST_SCHED_DEL_UNREF(sched, peer->expire,
-				unref_peer(peer, "remove register expire ref"));
-			expire_register(ref_peer(peer, "ref for expire_register"));
-			ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
+			AST_SCHED_DEL_UNREF(sched, peer->expire, unref_peer(peer, "remove register expire ref"));
+			unregister_peer(peer, NULL);
+			ast_cli(a->fd, "Unregistered peer \'%s\'\n", a->argv[2]);
 		} else {
-			ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
+			ast_cli(a->fd, "Peer \'%s\' not registered\n", a->argv[2]);
 		}
 		unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call");
 	} else {
