[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