[asterisk-commits] branch oej/metermaids-trunk r35509 - in /team/oej/metermaids-trunk: ./ apps/ ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Jun 22 08:50:33 MST 2006


Author: oej
Date: Thu Jun 22 10:50:33 2006
New Revision: 35509

URL: http://svn.digium.com/view/asterisk?rev=35509&view=rev
Log:
- Adding a new concept called "devicestate providers" to avoid using chan_local
- As a proof of concept, implementing these in meetme
- Need to move metermaids to devicestate providers too
- Messed around with group's as a provider - but, well, it will take a lot of work

Modified:
    team/oej/metermaids-trunk/app.c
    team/oej/metermaids-trunk/apps/app_meetme.c
    team/oej/metermaids-trunk/devicestate.c
    team/oej/metermaids-trunk/include/asterisk/devicestate.h
    team/oej/metermaids-trunk/pbx.c

Modified: team/oej/metermaids-trunk/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/app.c?rev=35509&r1=35508&r2=35509&view=diff
==============================================================================
--- team/oej/metermaids-trunk/app.c (original)
+++ team/oej/metermaids-trunk/app.c Thu Jun 22 10:50:33 2006
@@ -49,6 +49,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/lock.h"
 #include "asterisk/indications.h"
+#include "asterisk/devicestate.h"
 
 #define MAX_OTHER_FORMATS 10
 
@@ -797,12 +798,13 @@
 
 int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
 {
-	int res=0;
+	int res = 0;
 	char group[80] = "";
 	char category[80] = "";
 
 	if (!ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) {
 		pbx_builtin_setvar_helper(chan, category, group);
+		ast_device_state_changed("group:%s@%s", group, category);
 	} else
 		res = -1;
 

Modified: team/oej/metermaids-trunk/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/apps/app_meetme.c?rev=35509&r1=35508&r2=35509&view=diff
==============================================================================
--- team/oej/metermaids-trunk/apps/app_meetme.c (original)
+++ team/oej/metermaids-trunk/apps/app_meetme.c Thu Jun 22 10:50:33 2006
@@ -62,6 +62,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/translate.h"
 #include "asterisk/ulaw.h"
+#include "asterisk/devicestate.h"
 
 #include "enter.h"
 #include "leave.h"
@@ -278,7 +279,7 @@
 	int markedusers;                        /*!< Number of marked users */
 	time_t start;                           /*!< Start time (s) */
 	int refcount;                           /*!< reference count of usage */
-	enum recording_state recording:2;               /*!< recording status */
+	enum recording_state recording:2;       /*!< recording status */
 	unsigned int isdynamic:1;               /*!< Created on the fly? */
 	unsigned int locked:1;                  /*!< Is the conference locked? */
 	pthread_t recordthread;                 /*!< thread for recording */
@@ -970,6 +971,10 @@
 	/* Update table */
 	snprintf(members, sizeof(members), "%d", conf->users);
 	ast_update_realtime("meetme", "confno", conf->confno, "members", members , NULL);
+
+	/* This device changed state now - if this is the first user */
+	if (conf->users == 1)
+		ast_device_state_changed("meetme:%s", conf->confno);
 
 	ast_mutex_unlock(&conf->playlock);
 
@@ -1746,6 +1751,10 @@
 		/* Return the number of seconds the user was in the conf */
 		snprintf(meetmesecs, sizeof(meetmesecs), "%d", (int) (time(NULL) - user->jointime));
 		pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
+
+		/* This device changed state now */
+		if (!conf->users)	/* If there are no more members */
+			ast_device_state_changed("meetme:%s", conf->confno);
 	}
 	free(user);
 	AST_LIST_UNLOCK(&confs);
@@ -2514,6 +2523,29 @@
 	pthread_exit(0);
 }
 
+/*! \brief Callback for devicestate providers */
+static int meetmestates(const char *data)
+{
+	struct ast_conference *conf;
+
+	/* Find conference */
+	AST_LIST_LOCK(&confs);
+	AST_LIST_TRAVERSE(&confs, conf, list) {
+		if (!strcmp(data, conf->confno))
+			break;
+	}
+	AST_LIST_UNLOCK(&confs);
+	if (!conf)
+		return AST_DEVICE_INVALID;
+
+
+	/* SKREP to fill */
+	if (!conf->users)
+		return AST_DEVICE_NOT_INUSE;
+
+	return AST_DEVICE_INUSE;
+}
+
 static void load_config(void)
 {
 	struct ast_config *cfg;
@@ -2551,6 +2583,7 @@
 	res |= ast_unregister_application(app2);
 	res |= ast_unregister_application(app);
 
+	ast_devestate_prov_del("Meetme");
 	STANDARD_HANGUP_LOCALUSERS;
 
 	return res;
@@ -2569,6 +2602,7 @@
 	res |= ast_register_application(app2, count_exec, synopsis2, descrip2);
 	res |= ast_register_application(app, conf_exec, synopsis, descrip);
 
+	res |= ast_devstate_prov_add("Meetme", meetmestate);
 	return res;
 }
 

Modified: team/oej/metermaids-trunk/devicestate.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/devicestate.c?rev=35509&r1=35508&r2=35509&view=diff
==============================================================================
--- team/oej/metermaids-trunk/devicestate.c (original)
+++ team/oej/metermaids-trunk/devicestate.c Thu Jun 22 10:50:33 2006
@@ -40,6 +40,7 @@
 #include "asterisk/logger.h"
 #include "asterisk/devicestate.h"
 #include "asterisk/pbx.h"
+#include "asterisk/app.h"
 #include "asterisk/options.h"
 
 /*! \brief Device state strings for printing */
@@ -53,6 +54,16 @@
 	/* 6 AST_DEVICE_RINGING */	"Ringing"	/*!< Ring, ring, ring */
 };
 
+/*! \brief  A device state provider (not a channel) */
+struct devstate_prov {
+	char label[40];
+	ast_devstate_prov_cb_type callback;
+	AST_LIST_ENTRY(devstate_prov) list;
+};
+
+/*! \brief A list of providers */
+static AST_LIST_HEAD_STATIC(devstate_provs, devstate_prov);
+
 /*! \brief  A device state watcher (callback) */
 struct devstate_cb {
 	void *data;
@@ -60,6 +71,7 @@
 	AST_LIST_ENTRY(devstate_cb) list;
 };
 
+/*! \brief A device state watcher list */
 static AST_LIST_HEAD_STATIC(devstate_cbs, devstate_cb);
 
 struct state_change {
@@ -67,10 +79,18 @@
 	char device[1];
 };
 
+/*! \brief The state change queue. State changes are queued
+	for processing by a separate thread */
 static AST_LIST_HEAD_STATIC(state_changes, state_change);
 
+/*! \brief The device state change notification thread */
 static pthread_t change_thread = AST_PTHREADT_NULL;
+
+/*! \brief Flag for the queue */
 static ast_cond_t change_pending;
+
+/* Forward declarations */
+static int getproviderstate(const char *provider, const char *address);
 
 /*! \brief Find devicestate as text message for output */
 const char *devstate2str(int devstate) 
@@ -79,9 +99,9 @@
 }
 
 /*! \brief Find out if device is active in a call or not 
-\note find channels with the device's name in it
-This function is only used for channels that does not implement 
-devicestate natively
+	\note find channels with the device's name in it
+	This function is only used for channels that does not implement 
+	devicestate natively
 */
 int ast_parse_device_state(const char *device)
 {
@@ -110,17 +130,34 @@
 int ast_device_state(const char *device)
 {
 	char *buf;
-	char *tech;
 	char *number;
 	const struct ast_channel_tech *chan_tech;
 	int res = 0;
+	/*! \brief Channel driver that provides device state */
+	char *tech;
+	/*! \brief Another provider of device state */
+	char *provider = NULL;
 	
 	buf = ast_strdupa(device);
 	tech = strsep(&buf, "/");
 	number = buf;
-	if (!number)
-		return AST_DEVICE_INVALID;
-		
+	if (!number) {
+		number = strsep(&tech, ":");
+		if (!number)
+			return AST_DEVICE_INVALID;
+		/* We have a provider */
+		provider = tech;
+		tech = NULL;
+	}
+
+	if (provider)  {
+		if(option_debug > 2)
+			ast_log(LOG_DEBUG, "Checking if I can find provider for %s\n", provider);
+		return getproviderstate(provider, number);
+	}
+	if (option_debug > 3)
+		ast_log(LOG_DEBUG, "No provider found, checking channel drivers for %s - %s\n", tech, number);
+
 	chan_tech = ast_get_channel_tech(tech);
 	if (!chan_tech)
 		return AST_DEVICE_INVALID;
@@ -143,19 +180,75 @@
 	}
 }
 
+/*! \brief Add device state provider */
+int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
+{
+	struct devstate_prov *dpcb;
+
+	if (!callback || !(dpcb = ast_calloc(1, sizeof(*dpcb))))
+		return -1;
+
+	dpcb->callback = callback;
+	ast_copy_string(dpcb->label, label, sizeof(dpcb->label));
+
+	AST_LIST_LOCK(&devstate_provs);
+	AST_LIST_INSERT_HEAD(&devstate_provs, dpcb, list);
+	AST_LIST_UNLOCK(&devstate_provs);
+
+	return 0;
+}
+
+/*! \brief Remove device state provider */
+void ast_devstate_prov_del(const char *label)
+{
+	struct devstate_prov *devcb;
+
+	AST_LIST_LOCK(&devstate_provs);
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) {
+		if (!strcasecmp(devcb->label, label)) {
+			AST_LIST_REMOVE_CURRENT(&devstate_provs, list);
+			free(devcb);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+	AST_LIST_UNLOCK(&devstate_provs);
+}
+
+/*! \brief Get provider device state */
+static int getproviderstate(const char *provider, const char *address)
+{
+	struct devstate_prov *devprov;
+	int res = -1;
+
+
+	AST_LIST_LOCK(&devstate_provs);
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devprov, list) {
+		if(option_debug > 4)
+			ast_log(LOG_DEBUG, "Checking provider %s with %s\n", devprov->label, provider);
+		if (!strcasecmp(devprov->label, provider)) {
+			res = devprov->callback(address);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+	AST_LIST_UNLOCK(&devstate_provs);
+	return res == -1 ? AST_DEVICE_INVALID : res;
+}
+
 /*! \brief Add device state watcher */
 int ast_devstate_add(ast_devstate_cb_type callback, void *data)
 {
-	struct devstate_cb *devcb;
-
-	if (!callback || !(devcb = ast_calloc(1, sizeof(*devcb))))
+	struct devstate_cb *devprov;
+
+	if (!callback || !(devprov = ast_calloc(1, sizeof(*devprov))))
 		return -1;
 
-	devcb->data = data;
-	devcb->callback = callback;
+	devprov->data = data;
+	devprov->callback = callback;
 
 	AST_LIST_LOCK(&devstate_cbs);
-	AST_LIST_INSERT_HEAD(&devstate_cbs, devcb, list);
+	AST_LIST_INSERT_HEAD(&devstate_cbs, devprov, list);
 	AST_LIST_UNLOCK(&devstate_cbs);
 
 	return 0;
@@ -274,10 +367,32 @@
 	return NULL;
 }
 
+static int groupstate(const char *data)
+{
+	char *buf = ast_strdupa(data);
+	char *group = strsep(&buf, "@");
+	int count = 0;
+
+	if (option_debug > 2)
+		ast_log(LOG_DEBUG, "Group state checking for %s\n", buf);
+
+	if (buf) {
+		*buf = '\0';
+		buf++;
+	}
+	count = ast_app_group_get_count(group, buf);
+
+	if (!count)
+		return AST_DEVICE_NOT_INUSE;
+	else
+		return AST_DEVICE_INUSE;
+} 
+
 /*! \brief Initialize the device state engine in separate thread */
 int ast_device_state_engine_init(void)
 {
 	ast_cond_init(&change_pending, NULL);
+	ast_devstate_prov_add("group", groupstate);
 	if (ast_pthread_create(&change_thread, NULL, do_devstate_changes, NULL) < 0) {
 		ast_log(LOG_ERROR, "Unable to start device state change thread.\n");
 		return -1;

Modified: team/oej/metermaids-trunk/include/asterisk/devicestate.h
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/include/asterisk/devicestate.h?rev=35509&r1=35508&r2=35509&view=diff
==============================================================================
--- team/oej/metermaids-trunk/include/asterisk/devicestate.h (original)
+++ team/oej/metermaids-trunk/include/asterisk/devicestate.h Thu Jun 22 10:50:33 2006
@@ -44,7 +44,11 @@
 /*! Device is ringing *and* in use */
 #define AST_DEVICE_RINGINUSE	7
 
+/*! \brief Devicestate watcher call back */
 typedef int (*ast_devstate_cb_type)(const char *dev, int state, void *data);
+
+/*!  \brief Devicestate provider call back */
+typedef int (*ast_devstate_prov_cb_type)(const char *data);
 
 /*! \brief Convert device state to text string for output 
  * \param devstate Current device state 
@@ -95,7 +99,27 @@
  * Return -1 on failure, ID on success
  */ 
 int ast_devstate_add(ast_devstate_cb_type callback, void *data);
+
+/*! \brief Unregisters a device state change callback 
+ * \param callback Callback
+ * \param data to pass to callback
+ * The callback is called if the state for extension is changed
+ * Return -1 on failure, ID on success
+ */ 
 void ast_devstate_del(ast_devstate_cb_type callback, void *data);
+
+/*! \brief Add device state provider 
+ * \param label to use in hint, like label:object
+ * \param callback Callback
+ * Return -1 on failure, ID on success
+ */ 
+int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback);
+
+/*! \brief Remove device state provider 
+ * \param label to use in hint, like label:object
+ * Return -1 on failure, ID on success
+ */ 
+void ast_devstate_prov_del(const char *label);
 
 int ast_device_state_engine_init(void);
 

Modified: team/oej/metermaids-trunk/pbx.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/pbx.c?rev=35509&r1=35508&r2=35509&view=diff
==============================================================================
--- team/oej/metermaids-trunk/pbx.c (original)
+++ team/oej/metermaids-trunk/pbx.c Thu Jun 22 10:50:33 2006
@@ -188,7 +188,7 @@
 
 /*! \brief Structure for dial plan hints
 
-  Hints are pointers from an extension in the dialplan to one or
+  \note Hints are pointers from an extension in the dialplan to one or
   more devices (tech/name) */
 struct ast_hint {
 	struct ast_exten *exten;	/*!< Extension */



More information about the asterisk-commits mailing list