[asterisk-commits] branch oej/subscribemwi r10178 - /team/oej/subscribemwi/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Feb 14 23:56:35 MST 2006


Author: oej
Date: Wed Feb 15 00:56:33 2006
New Revision: 10178

URL: http://svn.digium.com/view/asterisk?rev=10178&view=rev
Log:
- Small fixes to handle peer destruction
- Actually send first MWI notification
- New config option to disable "normal" asterisk MWI behaviour while unsubscribed

Modified:
    team/oej/subscribemwi/channels/chan_sip.c

Modified: team/oej/subscribemwi/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/subscribemwi/channels/chan_sip.c?rev=10178&r1=10177&r2=10178&view=diff
==============================================================================
--- team/oej/subscribemwi/channels/chan_sip.c (original)
+++ team/oej/subscribemwi/channels/chan_sip.c Wed Feb 15 00:56:33 2006
@@ -600,6 +600,7 @@
 #define SIP_PAGE2_DEBUG_CONSOLE 	(1 << 6)
 #define SIP_PAGE2_DYNAMIC		(1 << 7)	/*!< Dynamic Peers register with Asterisk */
 #define SIP_PAGE2_SELFDESTRUCT		(1 << 8)	/*!< Automatic peers need to destruct themselves */
+#define SIP_PAGE2_SUBSCRIBEMWIONLY	(1 << 9)	/*!< Only issue MWI notification if subscribed to */
 
 /* SIP packet flags */
 #define SIP_PKT_DEBUG		(1 << 0)	/*!< Debug this packet */
@@ -712,7 +713,8 @@
 	
 	struct ast_dsp *vad;			/*!< Voice Activation Detection dsp */
 	
-	struct sip_peer *peerpoke;		/*!< If this dialog is to poke a peer, which one */
+	struct sip_peer *relatedpeer;		/*!< If this dialog is related to a peer, which one 
+							Used in peerpoke, mwi subscriptions */
 	struct sip_registry *registry;		/*!< If this is a REGISTER dialog, to which registry */
 	struct ast_rtp *rtp;			/*!< RTP Session */
 	struct ast_rtp *vrtp;			/*!< Video RTP session */
@@ -961,6 +963,8 @@
 static int find_sip_method(char *msg);
 static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
 static void sip_destroy(struct sip_pvt *p);
+static void sip_destroy_peer(struct sip_peer *peer);
+static void sip_destroy_user(struct sip_user *user);
 static void parse_request(struct sip_request *req);
 static char *get_header(struct sip_request *req, const char *name);
 static void copy_request(struct sip_request *dst,struct sip_request *src);
@@ -972,6 +976,7 @@
 static void set_peer_defaults(struct sip_peer *peer);
 static struct sip_peer *temp_peer(const char *name);
 static int sip_send_mwi_to_peer(struct sip_peer *peer);
+static int sip_scheddestroy(struct sip_pvt *p, int ms);
 
 
 /*----- RTP interface functions */
@@ -1685,6 +1690,11 @@
 	/* Delete it, it needs to disappear */
 	if (peer->call)
 		sip_destroy(peer->call);
+
+	if (peer->mwipvt) {	/* We have an active subscription, delete it */
+		sip_destroy(peer->mwipvt);
+	}
+
 	if (peer->chanvars) {
 		ast_variables_destroy(peer->chanvars);
 		peer->chanvars = NULL;
@@ -2165,6 +2175,11 @@
 
 	if (sip_debug_test_pvt(p) || option_debug > 2)
 		ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
+
+	/* Remove link from peer to subscription of MWI */
+	if (p->relatedpeer && p->relatedpeer->mwipvt)
+		p->relatedpeer->mwipvt = (struct sip_pvt *) NULL;
+
 	if (dumphistory)
 		sip_dump_history(p);
 
@@ -9813,7 +9828,7 @@
 	if (resp != 100) {
 		int statechanged = 0;
 		int newstate = 0;
-		peer = p->peerpoke;
+		peer = p->relatedpeer;
 		gettimeofday(&tv, NULL);
 		pingtime = ast_tvdiff_ms(tv, peer->ps);
 		if (pingtime < 1)
@@ -9893,7 +9908,7 @@
 		gettag(req, "To", tag, sizeof(tag));
 		ast_string_field_set(p, theirtag, tag);
 	}
-	if (p->peerpoke) {
+	if (p->relatedpeer && p->method == SIP_OPTIONS) {
 		/* We don't really care what the response is, just that it replied back. 
 		   Well, as long as it's not a 100 response...  since we might
 		   need to hang around for something more "definitive" */
@@ -10873,12 +10888,12 @@
 					transmit_response(p, "200 OK", req);
  					p->subscribed = MWI_NOTIFICATION;
 					authpeer->mwipvt = p;	/* Link from peer to pvt */
-					/* Do I need another the other way for destruction? */
+					p->relatedpeer = authpeer;	/* Link from pvt to peer */
 				} else {
 					transmit_response(p, "404 Not found", req);
 					ast_set_flag(p, SIP_NEEDDESTROY);	
+					return 0;
 				}
-				return 0;
 			} else { /* At this point, Asterisk does not understand the specified event */
 				transmit_response(p, "489 Bad Event", req);
 				if (option_debug > 1)
@@ -10902,8 +10917,12 @@
 		if (p->expiry < min_expiry && p->expiry > 0)
 			p->expiry = min_expiry;
 
-		if (sipdebug || option_debug > 1)
-			ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
+		if (sipdebug || option_debug > 1) {
+			if (p->subscribed == MWI_NOTIFICATION)
+				ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", authpeer->name, authpeer->mailbox);
+			else
+				ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
+		}
 		if (p->autokillid > -1)
 			sip_cancel_destroy(p);	/* Remove subscription expiry for renewals */
 		if (p->expiry > 0)
@@ -11293,7 +11312,11 @@
 	
 	peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
 
-	if (!peer->mwipvt) {
+	if (peer->mwipvt) {
+		/* Base message on subscription */
+		p = peer->mwipvt;
+	} else {
+		/* Build temporary dialog for this message */
 		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
 			return -1;
 		if (create_addr_from_peer(p, peer)) {
@@ -11306,13 +11329,12 @@
 			memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
 		build_via(p);
 		build_callid_pvt(p);
-	} else {
-		p = peer->mwipvt;
+		/* Destroy this session after 32 secs */
+		sip_scheddestroy(p, 32000);
 	}
 	/* Send MWI */
 	ast_set_flag(p, SIP_OUTGOING);
 	transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
-	sip_scheddestroy(p, 15000);
 	return 0;
 }
 
@@ -11427,10 +11449,20 @@
 		} while (0)
 		);
 		if (peer) {
-			ASTOBJ_WRLOCK(peer);
-			sip_send_mwi_to_peer(peer);
-			ASTOBJ_UNLOCK(peer);
-			ASTOBJ_UNREF(peer,sip_destroy_peer);
+			int sendmwi = TRUE;
+			/* If this peer requires subscription for mwi, check if we have
+				a subscription */
+			if(ast_test_flag((&peer->flags_page2), SIP_PAGE2_SUBSCRIBEMWIONLY)) {
+				if (!peer->mwipvt)
+					sendmwi = FALSE;
+			
+			}
+			if (sendmwi) {
+				ASTOBJ_WRLOCK(peer);
+				sip_send_mwi_to_peer(peer);
+				ASTOBJ_UNLOCK(peer);
+				ASTOBJ_UNREF(peer,sip_destroy_peer);
+			}
 		} else {
 			/* Reset where we come from */
 			lastpeernum = -1;
@@ -11540,7 +11572,7 @@
 
 	if (peer->pokeexpire > -1)
 		ast_sched_del(sched, peer->pokeexpire);
-	p->peerpoke = peer;
+	p->relatedpeer = peer;
 	ast_set_flag(p, SIP_OUTGOING);
 #ifdef VOCAL_DATA_HACK
 	ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
@@ -12268,6 +12300,9 @@
 			ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
 		} else if (!strcasecmp(v->name, "mailbox")) {
 			ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
+		} else if (realtime && !strcasecmp(v->name, "subscribemwi")) {
+			if (ast_true(v->value))
+				ast_set_flag((&peer->flags_page2), SIP_PAGE2_SUBSCRIBEMWIONLY);
 		} else if (!strcasecmp(v->name, "vmexten")) {
 			ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
 		} else if (!strcasecmp(v->name, "callgroup")) {



More information about the asterisk-commits mailing list