[asterisk-commits] oej: branch group/pinana-publish-1.4 r296505 - in /team/group/pinana-publish-...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Nov 27 14:00:02 CST 2010


Author: oej
Date: Sat Nov 27 13:59:57 2010
New Revision: 296505

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=296505
Log:
If we load a dialplan with a hint referring to a device state provider that is not yet
registered, the device state for the device in the hint will not be initialized.
For this solution, that means we can't set up a subscription.

Therefore I'm adding a reinitialization function run when a device state provider registers.
If we already have hints using this provider, we recheck their state. This way we get a first 
state and can set up services needed for the device state provider.

Actually proved that it worked to. Amazing.


Modified:
    team/group/pinana-publish-1.4/channels/chan_sip.c
    team/group/pinana-publish-1.4/include/asterisk/devicestate.h
    team/group/pinana-publish-1.4/include/asterisk/pbx.h
    team/group/pinana-publish-1.4/main/devicestate.c
    team/group/pinana-publish-1.4/main/pbx.c

Modified: team/group/pinana-publish-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/channels/chan_sip.c?view=diff&rev=296505&r1=296504&r2=296505
==============================================================================
--- team/group/pinana-publish-1.4/channels/chan_sip.c (original)
+++ team/group/pinana-publish-1.4/channels/chan_sip.c Sat Nov 27 13:59:57 2010
@@ -1257,7 +1257,10 @@
 	void (*destructor)(void *instance_data);
 };
 
-static void dlginfo_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry);
+static void dlginfo_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry)
+{
+	return;
+}
 
 static void dlginfo_epa_destructor(void *data)
 {
@@ -19152,6 +19155,8 @@
 	if (ast_strlen_zero(uri)) {
 		return -1;
 	}
+
+	ast_log(LOG_DEBUG, "--- Adding URI %s\n", uri);
 	
 	ast_copy_string(buf, uri, sizeof(buf));
 
@@ -19259,6 +19264,8 @@
 /* \brief Handle SIP response in SUBSCRIBE transaction */
 static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 {
+	int needdestroy = FALSE;
+
 	//Trunk: if (!p->mwi && !p->pres) {
 	if (!p->pres) {
 		return;
@@ -19288,7 +19295,8 @@
 			ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From"));
 			p->pres->call = NULL;
 			ASTOBJ_UNREF(p->pres, sip_subscribe_pres_destroy);
-			pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE");
+			needdestroy = TRUE;
+			//pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE");
 		}
 		break;
 	case 403:
@@ -19296,7 +19304,8 @@
 		ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for presence (URI: %s)\n", p->pres->uri);
 		p->pres->call = NULL;
 		ASTOBJ_UNREF(p->pres, sip_subscribe_pres_destroy);
-		pvt_set_needdestroy(p, "received 403 response");
+		needdestroy = TRUE;
+		//pvt_set_needdestroy(p, "received 403 response");
 		sip_alreadygone(p);
 		break;
 	case 404:
@@ -19304,14 +19313,16 @@
 		p->pres->call = NULL;
 		p->pres->fatalerror = TRUE;
 		ASTOBJ_UNREF(p->pres, sip_subscribe_pres_destroy);
-		pvt_set_needdestroy(p, "received 404 response");
+		needdestroy = TRUE;
+		//pvt_set_needdestroy(p, "received 404 response");
 		break;
 	case 481:
 		ast_log(LOG_WARNING, "Re-Subscription failed. The remote side said that our dialog did not exist.(URI: %s)\n", p->pres->uri);
 		p->pres->call = NULL;
 		ASTOBJ_UNREF(p->pres, sip_subscribe_pres_destroy);
 		/* In this case we need to start a new subscription, not give up */
-		pvt_set_needdestroy(p, "received 481 response");
+		needdestroy = TRUE;
+		//pvt_set_needdestroy(p, "received 481 response");
 		break;
 	case 500:
 	case 501:
@@ -19319,8 +19330,12 @@
 		p->pres->fatalerror = TRUE;
 		p->pres->call = NULL;
 		ASTOBJ_UNREF(p->pres, sip_subscribe_pres_destroy);
-		pvt_set_needdestroy(p, "received 500/501 response");
+		needdestroy = TRUE;
+		//pvt_set_needdestroy(p, "received 500/501 response");
 		break;
+	}
+	if (needdestroy) {
+		ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
 	}
 }
 
@@ -19346,10 +19361,9 @@
 	   we just answer back with a dummy answer. When we get the first notify later on,
 	   we'll update automatically with the initial state.
 	*/
-	
-
-	/* This is just a dummy */
-	return AST_DEVICE_INUSE;
+	sip_subscribe_pres(data, SUB_DIALOG_INFO);
+
+	return AST_DEVICE_UNKNOWN;
 }
 
 static void publisher_destructor_cb(void *data)

Modified: team/group/pinana-publish-1.4/include/asterisk/devicestate.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/include/asterisk/devicestate.h?view=diff&rev=296505&r1=296504&r2=296505
==============================================================================
--- team/group/pinana-publish-1.4/include/asterisk/devicestate.h (original)
+++ team/group/pinana-publish-1.4/include/asterisk/devicestate.h Sat Nov 27 13:59:57 2010
@@ -28,6 +28,7 @@
 #endif
 
 enum ast_device_state {
+	AST_DEVICE_PROV_NOT_FOUND,  /*!< Device state provider not found (to be able to initialize in step 2 */
 	AST_DEVICE_UNKNOWN,      /*!< Device is valid but channel didn't know state */
 	AST_DEVICE_NOT_INUSE,    /*!< Device is not used */
 	AST_DEVICE_INUSE,        /*!< Device is in use */

Modified: team/group/pinana-publish-1.4/include/asterisk/pbx.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/include/asterisk/pbx.h?view=diff&rev=296505&r1=296504&r2=296505
==============================================================================
--- team/group/pinana-publish-1.4/include/asterisk/pbx.h (original)
+++ team/group/pinana-publish-1.4/include/asterisk/pbx.h Sat Nov 27 13:59:57 2010
@@ -917,6 +917,11 @@
 
 void ast_hint_state_changed(const char *device);
 
+/*! \brief  ast_hint_reinit_provider: Reinitialize hints for a provider after provider
+	was added
+ */
+void ast_hint_reinit_provider(const char *provider);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/group/pinana-publish-1.4/main/devicestate.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/main/devicestate.c?view=diff&rev=296505&r1=296504&r2=296505
==============================================================================
--- team/group/pinana-publish-1.4/main/devicestate.c (original)
+++ team/group/pinana-publish-1.4/main/devicestate.c Sat Nov 27 13:59:57 2010
@@ -45,6 +45,7 @@
 
 /*! \brief Device state strings for printing */
 static const char *devstatestring[] = {
+	/* 0 AST_DEVICE_PROV_NOT_FOUND */    "Provider not found",    /*!< Provider not found */
 	/* 0 AST_DEVICE_UNKNOWN */    "Unknown",    /*!< Valid, but unknown state */
 	/* 1 AST_DEVICE_NOT_INUSE */  "Not in use", /*!< Not used */
 	/* 2 AST_DEVICE IN USE */     "In use",     /*!< In use */
@@ -145,8 +146,10 @@
 	number = buf;
 	if (!number) {
 		provider = strsep(&tech, ":");
-		if (!tech)
+		if (!tech) {
+			ast_log(LOG_ERROR, "Invalid device identifier: %s\n", provider);
 			return AST_DEVICE_INVALID;
+		}
 		/* We have a provider */
 		number = tech;
 		tech = NULL;
@@ -197,6 +200,9 @@
 	AST_LIST_INSERT_HEAD(&devstate_provs, devprov, list);
 	AST_LIST_UNLOCK(&devstate_provs);
 
+	/* Check if we have devices in the hint list that need initialization */
+	ast_hint_reinit_provider(label);
+
 	return 0;
 }
 
@@ -221,7 +227,7 @@
 static int getproviderstate(const char *provider, const char *address)
 {
 	struct devstate_prov *devprov;
-	int res = AST_DEVICE_INVALID;
+	int res = AST_DEVICE_PROV_NOT_FOUND;
 
 
 	AST_LIST_LOCK(&devstate_provs);
@@ -230,12 +236,19 @@
 			ast_log(LOG_DEBUG, "Checking provider %s with %s\n", devprov->label, provider);
 
 		if (!strcasecmp(devprov->label, provider)) {
+			if(option_debug > 1)
+				ast_log(LOG_DEBUG, "Found provider %s with %s:%s\n", devprov->label, provider, address);
 			res = devprov->callback(address);
 			break;
 		}
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
 	AST_LIST_UNLOCK(&devstate_provs);
+	if (res == AST_DEVICE_PROV_NOT_FOUND) {
+		if(option_debug > 1)
+			ast_log(LOG_DEBUG, "Found no valid device state for %s:%s\n", provider, address);
+		
+	}
 	return res;
 }
 
@@ -380,6 +393,7 @@
 void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
 {
 	switch (state) {
+	case AST_DEVICE_PROV_NOT_FOUND:
 	case AST_DEVICE_NOT_INUSE:
 		agg->all_unknown = 0;
 		agg->all_unavail = 0;

Modified: team/group/pinana-publish-1.4/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/main/pbx.c?view=diff&rev=296505&r1=296504&r2=296505
==============================================================================
--- team/group/pinana-publish-1.4/main/pbx.c (original)
+++ team/group/pinana-publish-1.4/main/pbx.c Sat Nov 27 13:59:57 2010
@@ -237,6 +237,7 @@
 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
 int pbx_builtin_setvar(struct ast_channel *, void *);
 static int pbx_builtin_importvar(struct ast_channel *, void *);
+static int ast_extension_state2(struct ast_exten *e);
 
 AST_MUTEX_DEFINE_STATIC(globalslock);
 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
@@ -1925,6 +1926,32 @@
 	}
 }
 
+
+/*! \brief  ast_hint_reinit_provider: Reinitialize hints for a provider after provider
+	was added
+ */
+void ast_hint_reinit_provider(const char *provider)
+{
+	struct ast_hint *hint;
+	struct ao2_iterator i;
+	const char *hinttext;
+
+	if (ao2_container_count(hints) == 0) {
+		return;
+	}
+
+	i = ao2_iterator_init(hints, 0);
+
+	for (hint = ao2_iterator_next(&i); hint; ao2_ref(hint, -1), hint = ao2_iterator_next(&i)) {
+		hinttext = ast_get_extension_app(hint->exten);
+		/* If we find the provider label in the hint, we need to reinitialize the hint */
+		if (strcasestr(hinttext, provider)) {
+			ast_extension_state2(hint->exten);
+		}
+	}
+	ao2_iterator_destroy(&i);
+}
+
 /*! \brief  ast_hint_extension: Find hint for given extension in context */
 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
 {
@@ -1958,6 +1985,7 @@
 		return AST_EXTENSION_INUSE;
 	case AST_DEVICE_NOT_INUSE:
 		return AST_EXTENSION_NOT_INUSE;
+	case AST_DEVICE_PROV_NOT_FOUND: /* not a device state, included for completeness */
 	case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
 		break;
 	}




More information about the asterisk-commits mailing list