[asterisk-commits] twilson: branch 1.8 r286189 - in /branches/1.8: channels/ funcs/ include/aste...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 10 17:04:58 CDT 2010
Author: twilson
Date: Fri Sep 10 17:04:53 2010
New Revision: 286189
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=286189
Log:
Merged revisions 286115 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
r286115 | twilson | 2010-09-10 15:35:25 -0500 (Fri, 10 Sep 2010) | 23 lines
Merged revisions 286059 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r286059 | twilson | 2010-09-10 14:25:08 -0500 (Fri, 10 Sep 2010) | 16 lines
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.8/channels/chan_local.c
branches/1.8/funcs/func_channel.c
branches/1.8/include/asterisk/channel.h
branches/1.8/include/asterisk/frame.h
branches/1.8/include/asterisk/pbx.h
Modified: branches/1.8/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_local.c?view=diff&rev=286189&r1=286188&r2=286189
==============================================================================
--- branches/1.8/channels/chan_local.c (original)
+++ branches/1.8/channels/chan_local.c Fri Sep 10 17:04:53 2010
@@ -95,6 +95,7 @@
static int local_devicestate(void *data);
static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
+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 = {
@@ -118,6 +119,7 @@
.devicestate = local_devicestate,
.bridged_channel = local_bridgedchannel,
.queryoption = local_queryoption,
+ .setoption = local_setoption,
};
/*! \brief the local pvt structure for all channels
@@ -150,6 +152,71 @@
#define LOCAL_MOH_PASSTHRU (1 << 6) /*!< 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 -1;
+ }
+
+ 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.8/funcs/func_channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/funcs/func_channel.c?view=diff&rev=286189&r1=286188&r2=286189
==============================================================================
--- branches/1.8/funcs/func_channel.c (original)
+++ branches/1.8/funcs/func_channel.c Fri Sep 10 17:04:53 2010
@@ -378,7 +378,7 @@
return ret;
}
-static int func_channel_write(struct ast_channel *chan, const char *function,
+static int func_channel_write_real(struct ast_channel *chan, const char *function,
char *data, const char *value)
{
int ret = 0;
@@ -496,6 +496,24 @@
return ret;
}
+static int func_channel_write(struct ast_channel *chan, const 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 = {
.name = "CHANNEL",
.read = func_channel_read,
Modified: branches/1.8/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/channel.h?view=diff&rev=286189&r1=286188&r2=286189
==============================================================================
--- branches/1.8/include/asterisk/channel.h (original)
+++ branches/1.8/include/asterisk/channel.h Fri Sep 10 17:04:53 2010
@@ -467,6 +467,27 @@
/*! What redirecting-to id information to set. */
struct ast_set_party_id to;
};
+
+/*! \brief Typedef for a custom read function */
+typedef int (*ast_acf_read_fn_t)(struct ast_channel *, const char *, char *, char *, size_t);
+
+/*! \brief Typedef for a custom read2 function */
+typedef int (*ast_acf_read2_fn_t)(struct ast_channel *, const char *, char *, struct ast_str **, ssize_t);
+
+/*! \brief Typedef for a custom write function */
+typedef int (*ast_acf_write_fn_t)(struct ast_channel *, const 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;
+ const char *function;
+ char *data;
+ const char *value;
+} ast_chan_write_info_t;
/*!
* \brief
Modified: branches/1.8/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/frame.h?view=diff&rev=286189&r1=286188&r2=286189
==============================================================================
--- branches/1.8/include/asterisk/frame.h (original)
+++ branches/1.8/include/asterisk/frame.h Fri Sep 10 17:04:53 2010
@@ -436,6 +436,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
+
/* !
* Read-only. Allows query current status of T38 on the channel.
* data: ast_t38state
Modified: branches/1.8/include/asterisk/pbx.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/pbx.h?view=diff&rev=286189&r1=286188&r2=286189
==============================================================================
--- branches/1.8/include/asterisk/pbx.h (original)
+++ branches/1.8/include/asterisk/pbx.h Fri Sep 10 17:04:53 2010
@@ -23,6 +23,7 @@
#ifndef _ASTERISK_PBX_H
#define _ASTERISK_PBX_H
+#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/devicestate.h"
#include "asterisk/chanvars.h"
@@ -89,7 +90,7 @@
);
enum ast_doc_src docsrc; /*!< Where the documentation come from */
/*! Read function, if read is supported */
- int (*read)(struct ast_channel *, const char *, char *, char *, size_t);
+ ast_acf_read_fn_t read; /*!< Read function, if read is supported */
/*! Read function, if read is supported. Note: only one of read or read2
* needs to be implemented. In new code, read2 should be implemented as
* the way forward, but they should return identical results, within the
@@ -97,11 +98,11 @@
* read function is handed a 16-byte buffer, and the result is 17 bytes
* long, then the first 15 bytes (remember NULL terminator) should be
* the same for both the read and the read2 methods. */
- int (*read2)(struct ast_channel *, const char *, char *, struct ast_str **, ssize_t);
+ ast_acf_read2_fn_t read2;
/*! If no read2 function is provided, what maximum size? */
size_t read_max;
/*! Write function, if write is supported */
- int (*write)(struct ast_channel *, const char *, char *, const char *);
+ ast_acf_write_fn_t write; /*!< Write function, if write is supported */
struct ast_module *mod; /*!< Module this custom function belongs to */
AST_RWLIST_ENTRY(ast_custom_function) acflist;
};
More information about the asterisk-commits
mailing list