[asterisk-commits] russell: trunk r385088 - in /trunk: CHANGES main/features.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 9 01:16:47 CDT 2013
Author: russell
Date: Tue Apr 9 01:16:42 2013
New Revision: 385088
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385088
Log:
Add inheritance support to FEATURE()/FEATUREMAP().
The settings saved on the channel for FEATURE()/FEATUREMAP() were only
for that channel. This patch adds the ability to have these settings
inherited to child channels if you set FEATURE(inherit)=yes.
Review: https://reviewboard.asterisk.org/r/2415/
Modified:
trunk/CHANGES
trunk/main/features.c
Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=385088&r1=385087&r2=385088
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Tue Apr 9 01:16:42 2013
@@ -88,6 +88,10 @@
* PARKINGSLOT and PARKEDLOT channel variables will now be set for a parked
channel even when comebactoorigin=yes
+
+ * You can now have the settings for a channel updated using the FEATURE()
+ and FEATUREMAP() functions inherited to child channels by setting
+ FEATURE(inherit)=yes.
Logging
-------------------
Modified: trunk/main/features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/features.c?view=diff&rev=385088&r1=385087&r2=385088
==============================================================================
--- trunk/main/features.c (original)
+++ trunk/main/features.c Tue Apr 9 01:16:42 2013
@@ -438,6 +438,7 @@
<para>The allowed values are:</para>
<enumlist>
<enum name="parkingtime"><para>Specified in seconds.</para></enum>
+ <enum name="inherit"><para>Inherit feature settings made in FEATURE or FEATUREMAP to child channels.</para></enum>
</enumlist>
</parameter>
</syntax>
@@ -3333,11 +3334,31 @@
* \todo XXX This isn't pretty. At some point it would be nice to have all
* of the global / [general] options in a config object that we store here
* instead of handling each one manually.
+ *
+ * \note If anything gets added here, don't forget to update
+ * feature_ds_duplicate, as well.
* */
unsigned int parkingtime;
unsigned int parkingtime_is_set:1;
};
+static int feature_exten_hash(const void *obj, int flags)
+{
+ const struct feature_exten *fe = obj;
+ const char *sname = obj;
+
+ return ast_str_hash(flags & OBJ_KEY ? sname : fe->sname);
+}
+
+static int feature_exten_cmp(void *obj, void *arg, int flags)
+{
+ const struct feature_exten *fe = obj, *fe2 = arg;
+ const char *sname = arg;
+
+ return !strcmp(fe->sname, flags & OBJ_KEY ? sname : fe2->sname) ?
+ CMP_MATCH | CMP_STOP : 0;
+}
+
static void feature_ds_destroy(void *data)
{
struct feature_ds *feature_ds = data;
@@ -3350,27 +3371,31 @@
ast_free(feature_ds);
}
+static void *feature_ds_duplicate(void *data)
+{
+ struct feature_ds *old_ds = data;
+ struct feature_ds *new_ds;
+
+ if (!(new_ds = ast_calloc(1, sizeof(*new_ds)))) {
+ return NULL;
+ }
+
+ if (old_ds->feature_map) {
+ ao2_ref(old_ds->feature_map, +1);
+ new_ds->feature_map = old_ds->feature_map;
+ }
+
+ new_ds->parkingtime = old_ds->parkingtime;
+ new_ds->parkingtime_is_set = old_ds->parkingtime_is_set;
+
+ return new_ds;
+}
+
static const struct ast_datastore_info feature_ds_info = {
.type = "FEATURE",
.destroy = feature_ds_destroy,
+ .duplicate = feature_ds_duplicate,
};
-
-static int feature_exten_hash(const void *obj, int flags)
-{
- const struct feature_exten *fe = obj;
- const char *sname = obj;
-
- return ast_str_hash(flags & OBJ_KEY ? sname : fe->sname);
-}
-
-static int feature_exten_cmp(void *obj, void *arg, int flags)
-{
- const struct feature_exten *fe = obj, *fe2 = arg;
- const char *sname = arg;
-
- return !strcmp(fe->sname, flags & OBJ_KEY ? sname : fe2->sname) ?
- CMP_MATCH | CMP_STOP : 0;
-}
/*!
* \internal
@@ -3409,6 +3434,19 @@
ast_channel_datastore_add(chan, ds);
return feature_ds;
+}
+
+static struct ast_datastore *get_feature_chan_ds(struct ast_channel *chan)
+{
+ struct ast_datastore *ds;
+
+ if (!(ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL))) {
+ /* Hasn't been created yet. Trigger creation. */
+ get_feature_ds(chan);
+ ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL);
+ }
+
+ return ds;
}
/*!
@@ -8964,6 +9002,16 @@
if (!strcasecmp(data, "parkingtime")) {
snprintf(buf, len, "%u", get_parkingtime(chan, NULL) / 1000);
+ } else if (!strcasecmp(data, "inherit")) {
+ struct ast_datastore *ds;
+ unsigned int inherit;
+
+ ast_channel_lock(chan);
+ ds = get_feature_chan_ds(chan);
+ inherit = ds ? ds->inheritance : 0;
+ ast_channel_unlock(chan);
+
+ snprintf(buf, len, "%s", inherit ? "yes" : "no");
} else {
ast_log(LOG_WARNING, "Invalid argument '%s' to FEATURE()\n", data);
res = -1;
@@ -8993,6 +9041,11 @@
ast_log(LOG_WARNING, "'%s' is not a valid parkingtime\n", value);
feature_ds->parkingtime_is_set = 0;
res = -1;
+ }
+ } else if (!strcasecmp(data, "inherit")) {
+ struct ast_datastore *ds;
+ if ((ds = get_feature_chan_ds(chan))) {
+ ds->inheritance = ast_true(value) ? DATASTORE_INHERIT_FOREVER : 0;
}
} else {
ast_log(LOG_WARNING, "Invalid argument '%s' to FEATURE()\n", data);
More information about the asterisk-commits
mailing list