[asterisk-commits] twilson: branch 1.4 r286059 - in /branches/1.4: channels/ funcs/ include/aste...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Sep 10 14:25:14 CDT 2010


Author: twilson
Date: Fri Sep 10 14:25:08 2010
New Revision: 286059

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=286059
Log:
Inherit CHANNEL() writes to both sides of a Local channel

Having Local (/n) channels as queue members and setting the language in the
extension with Set(CHANNEL(language)=fr) sets the language on the Local/...,2
channel. Hold time report playbacks happen on the Local/...,1 channel and
therefor do not play in the specified language.

This patch modifies func_channel_write to call the setoption callback and pass
the CHANNEL() write info to the callback. chan_local uses this information to
look up the other side of the channel and apply the same changes to it.

(closes issue #17673)
Reported by: Guggemand

Review: https://reviewboard.asterisk.org/r/903/

Modified:
    branches/1.4/channels/chan_local.c
    branches/1.4/funcs/func_channel.c
    branches/1.4/include/asterisk/channel.h
    branches/1.4/include/asterisk/frame.h
    branches/1.4/include/asterisk/pbx.h

Modified: branches/1.4/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/channels/chan_local.c?view=diff&rev=286059&r1=286058&r2=286059
==============================================================================
--- branches/1.4/channels/chan_local.c (original)
+++ branches/1.4/channels/chan_local.c Fri Sep 10 14:25:08 2010
@@ -79,6 +79,7 @@
 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
 static int local_sendtext(struct ast_channel *ast, const char *text);
 static int local_devicestate(void *data);
+static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
 
 /* PBX interface structure for channel registration */
 static const struct ast_channel_tech local_tech = {
@@ -100,6 +101,7 @@
 	.send_html = local_sendhtml,
 	.send_text = local_sendtext,
 	.devicestate = local_devicestate,
+	.setoption = local_setoption,
 };
 
 struct local_pvt {
@@ -123,6 +125,71 @@
 #define LOCAL_MOH_PASSTHRU    (1 << 5) /*!< Pass through music on hold start/stop frames */
 
 static AST_LIST_HEAD_STATIC(locals, local_pvt);
+
+static int local_setoption(struct ast_channel *chan, int option, void * data, int datalen)
+{
+	int res;
+	struct local_pvt *p;
+	struct ast_channel *otherchan;
+	ast_chan_write_info_t *write_info;
+
+	if (option != AST_OPTION_CHANNEL_WRITE) {
+		return 0;
+	}
+
+	write_info = data;
+
+	if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
+		ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
+		return -1;
+	}
+
+
+startover:
+	ast_channel_lock(chan);
+
+	p = chan->tech_pvt;
+	if (!p) {
+		ast_channel_unlock(chan);
+		ast_log(LOG_WARNING, "Could not update other side of %s, local_pvt went away.\n", chan->name);
+		return -1;
+	}
+
+	while (ast_mutex_trylock(&p->lock)) {
+		ast_channel_unlock(chan);
+		sched_yield();
+		ast_channel_lock(chan);
+		p = chan->tech_pvt;
+		if (!p) {
+			ast_channel_unlock(chan);
+			ast_log(LOG_WARNING, "Could not update other side of %s, local_pvt went away.\n", chan->name);
+			return -1;
+		}
+	}
+
+	otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
+
+	if (!otherchan || otherchan == write_info->chan) {
+		ast_mutex_unlock(&p->lock);
+		ast_channel_unlock(chan);
+		ast_log(LOG_WARNING, "Could not update other side of %s, other side went away.\n", chan->name);
+		return 0;
+	}
+
+	if (ast_channel_trylock(otherchan)) {
+		ast_mutex_unlock(&p->lock);
+		ast_channel_unlock(chan);
+		goto startover;
+	}
+
+	res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
+
+	ast_channel_unlock(otherchan);
+	ast_mutex_unlock(&p->lock);
+	ast_channel_unlock(chan);
+
+	return res;
+}
 
 /*! \brief Adds devicestate to local channels */
 static int local_devicestate(void *data)

Modified: branches/1.4/funcs/func_channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/funcs/func_channel.c?view=diff&rev=286059&r1=286058&r2=286059
==============================================================================
--- branches/1.4/funcs/func_channel.c (original)
+++ branches/1.4/funcs/func_channel.c Fri Sep 10 14:25:08 2010
@@ -96,7 +96,7 @@
 	return ret;
 }
 
-static int func_channel_write(struct ast_channel *chan, char *function,
+static int func_channel_write_real(struct ast_channel *chan, char *function,
 			      char *data, const char *value)
 {
 	int ret = 0;
@@ -137,6 +137,24 @@
 	}
 
 	return ret;
+}
+
+static int func_channel_write(struct ast_channel *chan, char *function, char *data, const char *value)
+{
+	int res;
+	ast_chan_write_info_t write_info = {
+		.version = AST_CHAN_WRITE_INFO_T_VERSION,
+		.write_fn = func_channel_write_real,
+		.chan = chan,
+		.function = function,
+		.data = data,
+		.value = value,
+	};
+
+	res = func_channel_write_real(chan, function, data, value);
+	ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);
+
+	return res;
 }
 
 static struct ast_custom_function channel_function = {

Modified: branches/1.4/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/channel.h?view=diff&rev=286059&r1=286058&r2=286059
==============================================================================
--- branches/1.4/include/asterisk/channel.h (original)
+++ branches/1.4/include/asterisk/channel.h Fri Sep 10 14:25:08 2010
@@ -193,6 +193,24 @@
 	int cid_ton;		/*!< Callerid Type of Number */
 	int cid_tns;		/*!< Callerid Transit Network Select */
 };
+
+/*! \brief Typedef for a custom read function */
+typedef int (*ast_acf_read_fn_t)(struct ast_channel *, char *, char *, char *, size_t);
+
+/*! \brief Typedef for a custom write function */
+typedef int (*ast_acf_write_fn_t)(struct ast_channel *, char *, char *, const char *);
+
+/*! \brief Structure to handle passing func_channel_write info to channels via setoption */
+typedef struct {
+	/*! \brief ast_chan_write_info_t version. Must be incremented if structure is changed */
+	#define AST_CHAN_WRITE_INFO_T_VERSION 1
+	uint32_t version;
+	ast_acf_write_fn_t write_fn;
+	struct ast_channel *chan;
+	char *function;
+	char *data;
+	const char *value;
+} ast_chan_write_info_t;
 
 /*! \brief 
 	Structure to describe a channel "technology", ie a channel driver 

Modified: branches/1.4/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/frame.h?view=diff&rev=286059&r1=286058&r2=286059
==============================================================================
--- branches/1.4/include/asterisk/frame.h (original)
+++ branches/1.4/include/asterisk/frame.h Fri Sep 10 14:25:08 2010
@@ -340,6 +340,13 @@
 /*! Explicitly enable or disable echo cancelation for the given channel */
 #define	AST_OPTION_ECHOCAN		8
 
+/*! \brief Handle channel write data
+ * If a channel needs to process the data from a func_channel write operation
+ * after func_channel_write executes, it can define the setoption callback
+ * and process this option. A pointer to an ast_chan_write_info_t will be passed.
+ * */
+#define AST_OPTION_CHANNEL_WRITE 9
+
 struct oprmode {
 	struct ast_channel *peer;
 	int mode;

Modified: branches/1.4/include/asterisk/pbx.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/include/asterisk/pbx.h?view=diff&rev=286059&r1=286058&r2=286059
==============================================================================
--- branches/1.4/include/asterisk/pbx.h (original)
+++ branches/1.4/include/asterisk/pbx.h Fri Sep 10 14:25:08 2010
@@ -71,8 +71,8 @@
 	const char *synopsis;		/*!< Short description for "show functions" */
 	const char *desc;		/*!< Help text that explains it all */
 	const char *syntax;		/*!< Syntax description */
-	int (*read)(struct ast_channel *, char *, char *, char *, size_t);	/*!< Read function, if read is supported */
-	int (*write)(struct ast_channel *, char *, char *, const char *);	/*!< Write function, if write is supported */
+	ast_acf_read_fn_t read;		/*!< Read function, if read is supported */
+	ast_acf_write_fn_t write;	/*!< Write function, if write is supported */
 	AST_LIST_ENTRY(ast_custom_function) acflist;
 };
 




More information about the asterisk-commits mailing list