[asterisk-commits] rmudgett: branch rmudgett/bridge_phase r387850 - in /team/rmudgett/bridge_pha...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue May 7 14:53:36 CDT 2013
Author: rmudgett
Date: Tue May 7 14:53:35 2013
New Revision: 387850
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387850
Log:
* Rename AST_UNREAL_MOH_PASSTHRU to AST_UNREAL_MOH_INTERCEPT and invert
the use of the flag to match the new name. This makes the unreal channels
default to not keeping state information in case they optimize.
* Refactor ast_unreal_indicate().
* Make unreal COLP handling always set caller information on the other
unreal channel in the pair.
Still to do:
* Move channels/chan_local.c to main/core_local.c and make it not dynamically loadable.
Modified:
team/rmudgett/bridge_phase/channels/chan_local.c
team/rmudgett/bridge_phase/include/asterisk/core_local.h
Modified: team/rmudgett/bridge_phase/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/channels/chan_local.c?view=diff&rev=387850&r1=387849&r2=387850
==============================================================================
--- team/rmudgett/bridge_phase/channels/chan_local.c (original)
+++ team/rmudgett/bridge_phase/channels/chan_local.c Tue May 7 14:53:35 2013
@@ -566,12 +566,127 @@
return 0;
}
+/*!
+ * \internal
+ * \brief Queue up a frame representing the indication as a control frame.
+ * \since 12.0.0
+ *
+ * \param p Unreal private structure.
+ * \param ast Channel indicating the condition.
+ * \param condition What is being indicated.
+ * \param data Extra data.
+ * \param datalen Length of extra data.
+ *
+ * \retval 0 on success.
+ * \retval AST_T38_REQUEST_PARMS if successful and condition is AST_CONTROL_T38_PARAMETERS.
+ * \retval -1 on error.
+ */
+static int unreal_queue_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition, const void *data, size_t datalen)
+{
+ int res = 0;
+ int isoutbound;
+
+ ao2_lock(p);
+ /*
+ * Block -1 stop tones events if we are to be optimized out. We
+ * don't need a flurry of these events on an unreal channel chain
+ * when initially connected to slow the optimization process.
+ */
+ if (0 <= condition || ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION)) {
+ struct ast_frame f = {
+ .frametype = AST_FRAME_CONTROL,
+ .subclass.integer = condition,
+ .data.ptr = (void *) data,
+ .datalen = datalen,
+ };
+
+ isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
+ res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
+ if (!res
+ && condition == AST_CONTROL_T38_PARAMETERS
+ && datalen == sizeof(struct ast_control_t38_parameters)) {
+ const struct ast_control_t38_parameters *parameters = data;
+
+ if (parameters->request_response == AST_T38_REQUEST_PARMS) {
+ res = AST_T38_REQUEST_PARMS;
+ }
+ }
+ } else {
+ ast_debug(4, "Blocked indication %d\n", condition);
+ }
+ ao2_unlock(p);
+
+ return res;
+}
+
+/*!
+ * \internal
+ * \brief Handle COLP and redirecting conditions.
+ * \since 12.0.0
+ *
+ * \param p Unreal private structure.
+ * \param ast Channel indicating the condition.
+ * \param condition What is being indicated.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int unreal_colp_redirect_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition)
+{
+ struct ast_channel *this_channel;
+ struct ast_channel *the_other_channel;
+ int isoutbound;
+ int res = 0;
+
+ /*
+ * A connected line update frame may only contain a partial
+ * amount of data, such as just a source, or just a ton, and not
+ * the full amount of information. However, the collected
+ * information is all stored in the outgoing channel's
+ * connectedline structure, so when receiving a connected line
+ * update on an outgoing unreal channel, we need to transmit the
+ * collected connected line information instead of whatever
+ * happens to be in this control frame. The same applies for
+ * redirecting information, which is why it is handled here as
+ * well.
+ */
+ ao2_lock(p);
+ isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
+ if (isoutbound) {
+ this_channel = p->chan;
+ the_other_channel = p->owner;
+ } else {
+ this_channel = p->owner;
+ the_other_channel = p->chan;
+ }
+ if (the_other_channel) {
+ unsigned char frame_data[1024];
+ struct ast_frame f = {
+ .frametype = AST_FRAME_CONTROL,
+ .subclass.integer = condition,
+ .data.ptr = frame_data,
+ };
+
+ if (condition == AST_CONTROL_CONNECTED_LINE) {
+ ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel),
+ ast_channel_connected(this_channel));
+ f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data),
+ ast_channel_connected(this_channel), NULL);
+ } else {
+ f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data),
+ ast_channel_redirecting(this_channel), NULL);
+ }
+ res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
+ }
+ ao2_unlock(p);
+
+ return res;
+}
+
int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
{
struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
int res = 0;
- struct ast_frame f = { AST_FRAME_CONTROL, };
- int isoutbound;
if (!p) {
return -1;
@@ -579,79 +694,28 @@
ao2_ref(p, 1); /* ref for unreal_queue_frame */
- /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
- if (!ast_test_flag(p, AST_UNREAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
- ast_moh_start(ast, data, NULL);
- } else if (!ast_test_flag(p, AST_UNREAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
- ast_moh_stop(ast);
- } else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
- struct ast_channel *this_channel;
- struct ast_channel *the_other_channel;
-
- /*
- * A connected line update frame may only contain a partial
- * amount of data, such as just a source, or just a ton, and not
- * the full amount of information. However, the collected
- * information is all stored in the outgoing channel's
- * connectedline structure, so when receiving a connected line
- * update on an outgoing unreal channel, we need to transmit the
- * collected connected line information instead of whatever
- * happens to be in this control frame. The same applies for
- * redirecting information, which is why it is handled here as
- * well.
- */
- ao2_lock(p);
- isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
- if (isoutbound) {
- this_channel = p->chan;
- the_other_channel = p->owner;
- } else {
- this_channel = p->owner;
- the_other_channel = p->chan;
- }
- if (the_other_channel) {
- unsigned char frame_data[1024];
-
- if (condition == AST_CONTROL_CONNECTED_LINE) {
- if (isoutbound) {
- ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel), ast_channel_connected(this_channel));
- }
- f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), ast_channel_connected(this_channel), NULL);
- } else {
- f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), ast_channel_redirecting(this_channel), NULL);
- }
- f.subclass.integer = condition;
- f.data.ptr = frame_data;
- res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
- }
- ao2_unlock(p);
- } else {
- /* Queue up a frame representing the indication as a control frame */
- ao2_lock(p);
- /*
- * Block -1 stop tones events if we are to be optimized out. We
- * don't need a flurry of these events on an unreal channel chain
- * when initially connected to slow the optimization process.
- */
- if (0 <= condition || ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION)) {
- isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
- f.subclass.integer = condition;
- f.data.ptr = (void *) data;
- f.datalen = datalen;
- res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
-
- if (!res && condition == AST_CONTROL_T38_PARAMETERS
- && datalen == sizeof(struct ast_control_t38_parameters)) {
- const struct ast_control_t38_parameters *parameters = data;
-
- if (parameters->request_response == AST_T38_REQUEST_PARMS) {
- res = AST_T38_REQUEST_PARMS;
- }
- }
- } else {
- ast_debug(4, "Blocked indication %d\n", condition);
- }
- ao2_unlock(p);
+ switch (condition) {
+ case AST_CONTROL_CONNECTED_LINE:
+ case AST_CONTROL_REDIRECTING:
+ res = unreal_colp_redirect_indicate(p, ast, condition);
+ break;
+ case AST_CONTROL_HOLD:
+ if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
+ ast_moh_start(ast, data, NULL);
+ break;
+ }
+ res = unreal_queue_indicate(p, ast, condition, data, datalen);
+ break;
+ case AST_CONTROL_UNHOLD:
+ if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
+ ast_moh_stop(ast);
+ break;
+ }
+ res = unreal_queue_indicate(p, ast, condition, data, datalen);
+ break;
+ default:
+ res = unreal_queue_indicate(p, ast, condition, data, datalen);
+ break;
}
ao2_ref(p, -1);
@@ -1237,6 +1301,16 @@
parse = ast_strdupa(data);
+ /*
+ * Local channels intercept MOH by default.
+ *
+ * This is a silly default because it represents state held by
+ * the local channels. Unless local channel optimization is
+ * disabled, the state will dissapear when the local channels
+ * optimize out.
+ */
+ ast_set_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
+
/* Look for options */
if ((opts = strchr(parse, '/'))) {
*opts++ = '\0';
@@ -1251,7 +1325,7 @@
}
}
if (strchr(opts, 'm')) {
- ast_set_flag(&pvt->base, AST_UNREAL_MOH_PASSTHRU);
+ ast_clear_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
}
}
Modified: team/rmudgett/bridge_phase/include/asterisk/core_local.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/core_local.h?view=diff&rev=387850&r1=387849&r2=387850
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/core_local.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/core_local.h Tue May 7 14:53:35 2013
@@ -58,7 +58,7 @@
#define AST_UNREAL_CARETAKER_THREAD (1 << 0) /*!< The ;2 side launched a PBX, was pushed into a bridge, or was masqueraded into an application. */
#define AST_UNREAL_NO_OPTIMIZATION (1 << 1) /*!< Do not optimize out the unreal channels */
-#define AST_UNREAL_MOH_PASSTHRU (1 << 2) /*!< Pass through hold start/stop frames */
+#define AST_UNREAL_MOH_INTERCEPT (1 << 2) /*!< Intercept and act on hold/unhold control frames */
/*!
* \brief Send an unreal pvt in with no locks held and get all locks
More information about the asterisk-commits
mailing list