[svn-commits] tilghman: branch tilghman/res_odbc_astobj2 r105480 - in /team/tilghman/res_od...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Feb 29 20:06:04 CST 2008


Author: tilghman
Date: Fri Feb 29 20:06:03 2008
New Revision: 105480

URL: http://svn.digium.com/view/asterisk?view=rev&rev=105480
Log:
Merged revisions 105461,105477,105479 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
r105461 | russell | 2008-02-29 18:53:25 -0600 (Fri, 29 Feb 2008) | 9 lines

Add a "devstate change" CLI command to control custom device states.  Also,
do some additional code cleanup and improvement in passing.

(closes issue #12106)
Reported by: nizon
Patches:
      devstate-patch.txt uploaded by nizon (license 415)
        -- Updated to trunk, and tab completion added by me

........
r105477 | twilson | 2008-02-29 19:30:37 -0600 (Fri, 29 Feb 2008) | 6 lines

Asterisk, when parking can drop rights a caller when a parking timeout occurs.  Also, when doing built-in attended transfers, sometimes incorrectly passes rights from the transferrer to the transferee.  This patch tries to fixes the parking issue and lays some groundwork for later fixing the transfer issue.

(closes issue #11520)
Reported by: pliew
Tested by: otherwiseguy

........
r105479 | tilghman | 2008-02-29 20:03:51 -0600 (Fri, 29 Feb 2008) | 2 lines

Drop bad property

........

Modified:
    team/tilghman/res_odbc_astobj2/   (props changed)
    team/tilghman/res_odbc_astobj2/CHANGES
    team/tilghman/res_odbc_astobj2/apps/app_dial.c
    team/tilghman/res_odbc_astobj2/funcs/func_devstate.c
    team/tilghman/res_odbc_astobj2/include/asterisk/app.h
    team/tilghman/res_odbc_astobj2/include/asterisk/global_datastores.h
    team/tilghman/res_odbc_astobj2/main/app.c
    team/tilghman/res_odbc_astobj2/main/features.c
    team/tilghman/res_odbc_astobj2/main/global_datastores.c

Propchange: team/tilghman/res_odbc_astobj2/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Feb 29 20:06:03 2008
@@ -1,1 +1,1 @@
-/trunk:1-105456
+/trunk:1-105479

Modified: team/tilghman/res_odbc_astobj2/CHANGES
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/CHANGES?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/CHANGES (original)
+++ team/tilghman/res_odbc_astobj2/CHANGES Fri Feb 29 20:06:03 2008
@@ -97,6 +97,9 @@
   * New CLI command: "core set chanvar" to set a channel variable from the CLI.
   * Added an easy way to execute Asterisk CLI commands at startup.  Any commands
     listed in the startup_commands section of cli.conf will get executed.
+  * Added a CLI command, "devstate change", which allows you to set custom device
+     states from the func_devstate module that provides the DEVICE_STATE() function
+     and handling of the "Custom:" devices.
 
 SIP changes
 -----------
@@ -166,7 +169,7 @@
   * Proper codec support in chan_skinny.
   * Added settings for IP and Ethernet QoS requests
 
-MGCP changes
+
 ------------
   * Added separate settings for media QoS in mgcp.conf
 

Modified: team/tilghman/res_odbc_astobj2/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/apps/app_dial.c?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/apps/app_dial.c (original)
+++ team/tilghman/res_odbc_astobj2/apps/app_dial.c Fri Feb 29 20:06:03 2008
@@ -1208,6 +1208,19 @@
 	return 1; /* success */
 }
 
+static void set_dial_features(struct ast_flags64 *opts, struct ast_dial_features *features)
+{
+	struct ast_flags64 perm_opts = {.flags = 0};
+
+	ast_copy_flags64(&perm_opts, opts,
+		OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_MIXMONITOR | OPT_CALLER_HANGUP |
+		OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_MIXMONITOR | OPT_CALLEE_HANGUP);
+
+	memset(features->options, 0, sizeof(features->options));
+
+	ast_app_options2str64(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
+}
+
 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec)
 {
 	int res = -1; /* default: error */
@@ -1243,6 +1256,9 @@
 	struct ast_flags64 opts = { 0, };
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
 	struct ast_datastore *datastore = NULL;
+	struct ast_datastore *ds_caller_features = NULL;
+	struct ast_datastore *ds_callee_features = NULL;
+	struct ast_dial_features *caller_features;
 	int fulldial = 0, num_dialed = 0;
 
 	if (ast_strlen_zero(data)) {
@@ -1316,6 +1332,29 @@
 	}
 
 	ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
+
+	/* Create datastore for channel dial features for caller */
+	if (!(ds_caller_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
+		ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
+		goto out;
+	}
+
+	if (!(caller_features = ast_malloc(sizeof(*caller_features)))) {
+		ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
+		goto out;
+	}
+
+	ast_copy_flags(&(caller_features->features_callee), &(config.features_caller), AST_FLAGS_ALL);
+	caller_features->is_caller = 1;
+	set_dial_features(&opts, caller_features);
+
+	ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
+	ds_caller_features->data = caller_features;
+
+	ast_channel_lock(chan);
+	ast_channel_datastore_add(chan, ds_caller_features);
+	ast_channel_unlock(chan);
+
 	/* loop through the list of dial destinations */
 	rest = args.peers;
 	while ((cur = strsep(&rest, "&")) ) {
@@ -1327,6 +1366,7 @@
 		char *tech = strsep(&number, "/");
 		/* find if we already dialed this interface */
 		struct ast_dialed_interface *di;
+		struct ast_dial_features *callee_features;
 		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
 		num_dialed++;
 		if (!number) {
@@ -1465,6 +1505,30 @@
 			ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
 		else
 			ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
+
+		/* Save callee features */
+		if (!(ds_callee_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
+			ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
+			ast_free(tmp);
+			goto out;
+		}
+
+		if (!(callee_features = ast_malloc(sizeof(*callee_features)))) {
+			ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
+			ast_free(tmp);
+			goto out;
+		}
+
+		ast_copy_flags(&(callee_features->features_callee), &(config.features_callee), AST_FLAGS_ALL);
+		callee_features->is_caller = 0;
+		set_dial_features(&opts, callee_features);
+
+		ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
+		ds_callee_features->data = callee_features;
+
+		ast_channel_lock(chan);
+		ast_channel_datastore_add(tc, ds_callee_features);
+		ast_channel_unlock(chan);
 
 		res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
 

Modified: team/tilghman/res_odbc_astobj2/funcs/func_devstate.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/funcs/func_devstate.c?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/funcs/func_devstate.c (original)
+++ team/tilghman/res_odbc_astobj2/funcs/func_devstate.c Fri Feb 29 20:06:03 2008
@@ -54,6 +54,7 @@
 static int devstate_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
 {
 	size_t len = strlen("Custom:");
+	enum ast_device_state state_val;
 
 	if (strncasecmp(data, "Custom:", len)) {
 		ast_log(LOG_WARNING, "The DEVICE_STATE function can only be used to set 'Custom:' device state!\n");
@@ -65,9 +66,16 @@
 		return -1;
 	}
 
+	state_val = ast_devstate_val(value);
+
+	if (state_val == AST_DEVICE_UNKNOWN) {
+		ast_log(LOG_ERROR, "DEVICE_STATE function given invalid state value '%s'\n", value);
+		return -1;
+	}
+
 	ast_db_put(astdb_family, data, value);
 
-	ast_devstate_changed(ast_devstate_val(value), "Custom:%s", data);
+	ast_devstate_changed(state_val, "Custom:%s", data);
 
 	return 0;
 }
@@ -215,9 +223,73 @@
 	return CLI_SUCCESS;
 }
 
+static char *handle_cli_devstate_change(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+    size_t len;
+	const char *dev, *state;
+	enum ast_device_state state_val;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "devstate change";
+		e->usage =
+			"Usage: devstate change <device> <state>\n"
+			"       Change a custom device to a new state.\n"
+			"       The possible values for the state are:\n"
+			"UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING\n"
+			"RINGINUSE | ONHOLD\n",
+			"\n"
+			"Examples:\n"
+			"       devstate change Custom:mystate1 INUSE\n"
+			"       devstate change Custom:mystate1 NOT_INUSE\n"
+			"       \n";
+		return NULL;
+	case CLI_GENERATE:
+	{
+		static char * const cmds[] = { "UNKNOWN", "NOT_INUSE", "INUSE", "BUSY",
+			"UNAVAILALBE", "RINGING", "RINGINUSE", "ONHOLD", NULL };
+
+		if (a->pos == e->args + 1)
+			return ast_cli_complete(a->word, cmds, a->n);
+
+		return NULL;
+	}
+	}
+
+	if (a->argc != e->args + 2)
+		return CLI_SHOWUSAGE;
+
+	len = strlen("Custom:");
+	dev = a->argv[e->args];
+	state = a->argv[e->args + 1];
+
+	if (strncasecmp(dev, "Custom:", len)) {
+		ast_cli(a->fd, "The devstate command can only be used to set 'Custom:' device state!\n");
+		return CLI_FAILURE;
+	}
+
+	dev += len;
+	if (ast_strlen_zero(dev))
+		return CLI_SHOWUSAGE;
+
+	state_val = ast_devstate_val(state);
+
+	if (state_val == AST_DEVICE_UNKNOWN)
+		return CLI_SHOWUSAGE;
+
+	ast_cli(a->fd, "Changing %s to %s\n", dev, state);
+
+	ast_db_put(astdb_family, dev, state);
+
+	ast_devstate_changed(state_val, "Custom:%s", dev);
+
+	return CLI_SUCCESS;
+}
+
 static struct ast_cli_entry cli_funcdevstate_list_deprecated = AST_CLI_DEFINE(handle_cli_funcdevstate_list, "List currently known custom device states");
 static struct ast_cli_entry cli_funcdevstate[] = {
 	AST_CLI_DEFINE(handle_cli_devstate_list, "List currently known custom device states", .deprecate_cmd = &cli_funcdevstate_list_deprecated),
+	AST_CLI_DEFINE(handle_cli_devstate_change, "Change a custom device state"),
 };
 
 static struct ast_custom_function devstate_function = {

Modified: team/tilghman/res_odbc_astobj2/include/asterisk/app.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/include/asterisk/app.h?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/include/asterisk/app.h (original)
+++ team/tilghman/res_odbc_astobj2/include/asterisk/app.h Fri Feb 29 20:06:03 2008
@@ -461,8 +461,16 @@
  */
 int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr);
 
-/*! \brief Present a dialtone and collect a certain length extension. 
-    \return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension. 
+/*! \brief Given a list of options array, return an option string based on passed flags
+	\param options The array of possible options declared with AST_APP_OPTIONS
+	\param flags The flags of the options that you wish to populate the buffer with
+	\param buf The buffer to fill with the string of options
+	\param len The maximum length of buf
+*/
+void ast_app_options2str64(const struct ast_app_option *options, struct ast_flags64 *flags, char *buf, size_t len);
+
+/*! \brief Present a dialtone and collect a certain length extension.
+    \return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
 \note Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
 int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
 

Modified: team/tilghman/res_odbc_astobj2/include/asterisk/global_datastores.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/include/asterisk/global_datastores.h?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/include/asterisk/global_datastores.h (original)
+++ team/tilghman/res_odbc_astobj2/include/asterisk/global_datastores.h Fri Feb 29 20:06:03 2008
@@ -26,11 +26,22 @@
 
 #include "asterisk/channel.h"
 
+#define MAX_DIAL_FEATURE_OPTIONS 30
+
 extern const struct ast_datastore_info dialed_interface_info;
+
+extern const struct ast_datastore_info dial_features_info;
 
 struct ast_dialed_interface {
 	AST_LIST_ENTRY(ast_dialed_interface) list;
 	char interface[1];
 };
 
+struct ast_dial_features {
+	struct ast_flags features_caller;
+	struct ast_flags features_callee;
+	char options[MAX_DIAL_FEATURE_OPTIONS];
+	int is_caller;
+};
+
 #endif

Modified: team/tilghman/res_odbc_astobj2/main/app.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/main/app.c?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/main/app.c (original)
+++ team/tilghman/res_odbc_astobj2/main/app.c Fri Feb 29 20:06:03 2008
@@ -1670,6 +1670,17 @@
 	return res;
 }
 
+void ast_app_options2str64(const struct ast_app_option *options, struct ast_flags64 *flags, char *buf, size_t len)
+{
+	unsigned int i, found = 0;
+	for (i = 32; i < 128 && found < len; i++) {
+		if (ast_test_flag64(flags, options[i].flag)) {
+			buf[found++] = i;
+		}
+	}
+	buf[found] = '\0';
+}
+
 int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
 {
 	int i;

Modified: team/tilghman/res_odbc_astobj2/main/features.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/main/features.c?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/main/features.c (original)
+++ team/tilghman/res_odbc_astobj2/main/features.c Fri Feb 29 20:06:03 2008
@@ -53,6 +53,7 @@
 #include "asterisk/devicestate.h"
 #include "asterisk/monitor.h"
 #include "asterisk/audiohook.h"
+#include "asterisk/global_datastores.h"
 
 #define DEFAULT_PARK_TIME 45000
 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
@@ -2232,10 +2233,24 @@
 					}
 					if (con) {
 						char returnexten[AST_MAX_EXTENSION];
-						snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
+						struct ast_datastore *features_datastore;
+						struct ast_dial_features *dialfeatures = NULL;
+
+						ast_channel_lock(chan);
+
+						if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
+							dialfeatures = features_datastore->data;
+
+						ast_channel_unlock(chan);
+
+						if (dialfeatures)
+							snprintf(returnexten, sizeof(returnexten), "%s,,%s", peername, dialfeatures->options);
+						else /* Existing default */
+							snprintf(returnexten, sizeof(returnexten), "%s,,t", peername);
+
 						ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
 					}
-					if (comebacktoorigin) { 
+					if (comebacktoorigin) {
 						set_c_e_p(chan, parking_con_dial, peername_flat, 1);
 					} else {
 						ast_log(LOG_WARNING, "now going to parkedcallstimeout,s,1 | ps is %d\n",pu->parkingnum);

Modified: team/tilghman/res_odbc_astobj2/main/global_datastores.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/res_odbc_astobj2/main/global_datastores.c?view=diff&rev=105480&r1=105479&r2=105480
==============================================================================
--- team/tilghman/res_odbc_astobj2/main/global_datastores.c (original)
+++ team/tilghman/res_odbc_astobj2/main/global_datastores.c Fri Feb 29 20:06:03 2008
@@ -35,8 +35,9 @@
 	struct ast_dialed_interface *di = NULL;
 	AST_LIST_HEAD(, ast_dialed_interface) *dialed_interface_list = data;
 	
-	if (!dialed_interface_list)
+	if (!dialed_interface_list) {
 		return;
+	}
 
 	AST_LIST_LOCK(dialed_interface_list);
 	while ((di = AST_LIST_REMOVE_HEAD(dialed_interface_list, list)))
@@ -53,11 +54,13 @@
 	AST_LIST_HEAD(, ast_dialed_interface) *old_list;
 	AST_LIST_HEAD(, ast_dialed_interface) *new_list = NULL;
 
-	if(!(old_list = data))
+	if(!(old_list = data)) {
 		return NULL;
+	}
 
-	if(!(new_list = ast_calloc(1, sizeof(*new_list))))
+	if(!(new_list = ast_calloc(1, sizeof(*new_list)))) {
 		return NULL;
+	}
 
 	AST_LIST_HEAD_INIT(new_list);
 	AST_LIST_LOCK(old_list);
@@ -76,8 +79,35 @@
 	return new_list;
 }
 
+
+static void *dial_features_duplicate(void *data)
+{
+	struct ast_dial_features *df = data, *df_copy;
+
+	if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
+		return NULL;
+	}
+
+	memcpy(df_copy, df, sizeof(*df));
+
+	return df_copy;
+}
+
+static void dial_features_destroy(void *data) {
+	struct ast_dial_features *df = data;
+	if (df) {
+		ast_free(df);
+	}
+}
+
 const struct ast_datastore_info dialed_interface_info = {
-	.type ="dialed-interface",
+	.type = "dialed-interface",
 	.destroy = dialed_interface_destroy,
 	.duplicate = dialed_interface_duplicate,
 };
+
+const struct ast_datastore_info dial_features_info = {
+	.type = "dial-features",
+	.destroy = dial_features_destroy,
+	.duplicate = dial_features_duplicate,
+};




More information about the svn-commits mailing list