[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