[asterisk-commits] branch bweschke/polycom_acd_functions - r7704 /team/bweschke/polycom_acd_func...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Jan 1 13:14:26 CST 2006


Author: bweschke
Date: Sun Jan  1 13:14:24 2006
New Revision: 7704

URL: http://svn.digium.com/view/asterisk?rev=7704&view=rev
Log:
 Bringing in changes from bug #6047. (Keeping SIP subscriptions around after a 'reload')


Modified:
    team/bweschke/polycom_acd_functions/channels/chan_sip.c

Modified: team/bweschke/polycom_acd_functions/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/bweschke/polycom_acd_functions/channels/chan_sip.c?rev=7704&r1=7703&r2=7704&view=diff
==============================================================================
--- team/bweschke/polycom_acd_functions/channels/chan_sip.c (original)
+++ team/bweschke/polycom_acd_functions/channels/chan_sip.c Sun Jan  1 13:14:24 2006
@@ -509,6 +509,14 @@
 	char secret[256];               /*!< Secret */
 	char md5secret[256];            /*!< MD5Secret */
 	struct sip_auth *next;          /*!< Next auth structure in list */
+};
+
+/*! \brief hintmgrparam: A structure to hold on to pointers for cb_hintmanager */
+struct hintmgrparam {
+	int state;			/*!< The original state causing the cb */
+	char *context;                  /*!< Context the hint is for */
+	char *exten;                    /*!< Extension the hint is for */
+	struct sip_pvt *p;              /*!< SIP Session Structure Ptr */
 };
 
 #define SIP_ALREADYGONE		(1 << 0)	/*!< Whether or not we've already been destroyed by our peer */
@@ -928,6 +936,7 @@
 static int determine_firstline_parts(struct sip_request *req);
 static void sip_dump_history(struct sip_pvt *dialog);	/* Dump history to LOG_DEBUG at end of dialog, before destroying data */
 static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
+static int cb_extensionstate(char *context, char* exten, int state, void *data);
 static int transmit_state_notify(struct sip_pvt *p, int state, int full, int substate);
 static char *gettag(struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
 int find_sip_method(char *msg);
@@ -6291,29 +6300,70 @@
 	return res;
 }
 
+/*! \brief  cb_hintmanager: Callback to check on the status of an AST_EXTENSION_DEACTIVATED/REMOVED call already received ---*/
+/*    When you do a 'reload' in Asterisk the ast_merge_contexts_and_delete() function call that gets
+      called during the reload will rebuild hints sending AST_EXTENSION_DEACTIVATED state msgs. Now, instead of 
+      acting immediately on those msgs, we schedule this callback for 5 secs later and if the hint is 
+      still not there, then we tear down the subscription, otherwise, we re-establish our connection with 
+      the core and re-sync and re-transmit current state. */
+static int cb_hintmanager(void *data)
+{
+	struct hintmgrparam *hmgrp = data;
+	struct sip_pvt *p = NULL;
+	int firststate = hmgrp->state;
+
+	/* Verify first that the SIP session is still around after having waited 5 secs */
+	if (hmgrp->p) {
+		p = hmgrp->p;
+		p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
+		ast_log(LOG_DEBUG, "ast_extension_state on %s@%s is %d\n", p->exten, p->context, ast_extension_state(NULL, p->context, p->exten));
+                if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
+                        ast_log(LOG_DEBUG, "Still cannot retrieve state on %s@%s. Time to throw in the towel.\n", p->exten, p->context);
+			if (p->autokillid > -1)
+				sip_cancel_destroy(p);         /* Remove subscription expiry for renewals */
+			sip_scheddestroy(p, 10000);            /* Delete subscription in 10 more secs since we've already waited 5 */
+			ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", hmgrp->exten, hmgrp->state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
+			p->stateid = -1;
+			p->subscribed = NONE;
+			append_history(p, "Subscribestatus", hmgrp->state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
+			transmit_state_notify(p, hmgrp->state, 1, 1);
+                } else {
+			if (option_debug > 1)
+				ast_verbose(VERBOSE_PREFIX_1 "Extension State Resync %s new state %s for Notify User %s\n", hmgrp->exten, ast_extension_state2str(firststate), p->username);
+                        transmit_state_notify(p, firststate, 1, 1);     /* Send current notification */
+		}	
+	} else
+		ast_log(LOG_DEBUG, "The SIP Session has gone away while we were waiting to be called back. Cleaning up and done.\n");
+
+	free(hmgrp);
+	return 0;
+}
+
 /*! \brief  cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---*/
 /*    If you add an "hint" priority to the extension in the dial plan,
       you will get notifications on device state changes */
 static int cb_extensionstate(char *context, char* exten, int state, void *data)
 {
 	struct sip_pvt *p = data;
+	struct hintmgrparam *hmgrp = NULL;
 
 	switch(state) {
 	case AST_EXTENSION_DEACTIVATED:	/* Retry after a while */
 	case AST_EXTENSION_REMOVED:	/* Extension is gone */
-		if (p->autokillid > -1)
-			sip_cancel_destroy(p);	/* Remove subscription expiry for renewals */
-		sip_scheddestroy(p, 15000);	/* Delete subscription in 15 secs */
-		ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
-		p->stateid = -1;
-		p->subscribed = NONE;
-		append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
+		hmgrp = malloc(sizeof(struct hintmgrparam));
+		hmgrp->state = state;
+		hmgrp->context = context;
+		hmgrp->exten = exten;
+		hmgrp->p = p;
+		ast_sched_add(sched, 5000, cb_hintmanager, hmgrp);
 		break;
 	default:	/* Tell user */
 		p->laststate = state;
 		break;
 	}
-	transmit_state_notify(p, state, 1, 1);
+
+	if (state != AST_EXTENSION_DEACTIVATED && state != AST_EXTENSION_REMOVED)
+		transmit_state_notify(p, state, 1, 1);
 
 	if (option_debug > 1)
 		ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);



More information about the asterisk-commits mailing list