[asterisk-commits] rmudgett: branch rmudgett/native_dahdi r394277 - in /team/rmudgett/native_dah...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jul 12 21:57:45 CDT 2013


Author: rmudgett
Date: Fri Jul 12 21:57:43 2013
New Revision: 394277

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394277
Log:
Commit work in progress.

* Made write AST_NULL_FRAME's into the bridge instead of immediately
discarding them after reading.  The bridge technology may need the
activity to determine if it needs to switch modes.

* Fill in more technology callbacks.  Just about the only thing remaining
is to actually start and stop the DAHDI mixing conference.

Modified:
    team/rmudgett/native_dahdi/bridges/bridge_softmix.c
    team/rmudgett/native_dahdi/channels/chan_dahdi.c
    team/rmudgett/native_dahdi/channels/chan_dahdi.h
    team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c
    team/rmudgett/native_dahdi/main/bridging.c

Modified: team/rmudgett/native_dahdi/bridges/bridge_softmix.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/native_dahdi/bridges/bridge_softmix.c?view=diff&rev=394277&r1=394276&r2=394277
==============================================================================
--- team/rmudgett/native_dahdi/bridges/bridge_softmix.c (original)
+++ team/rmudgett/native_dahdi/bridges/bridge_softmix.c Fri Jul 12 21:57:43 2013
@@ -623,6 +623,9 @@
 	}
 
 	switch (frame->frametype) {
+	case AST_FRAME_NULL:
+		/* "Accept" the frame and discard it. */
+		break;
 	case AST_FRAME_DTMF_BEGIN:
 	case AST_FRAME_DTMF_END:
 		res = ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);

Modified: team/rmudgett/native_dahdi/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/native_dahdi/channels/chan_dahdi.c?view=diff&rev=394277&r1=394276&r2=394277
==============================================================================
--- team/rmudgett/native_dahdi/channels/chan_dahdi.c (original)
+++ team/rmudgett/native_dahdi/channels/chan_dahdi.c Fri Jul 12 21:57:43 2013
@@ -2424,9 +2424,6 @@
 	return par.rxisoffhook;
 }
 
-static void dahdi_enable_ec(struct dahdi_pvt *p);
-static void dahdi_disable_ec(struct dahdi_pvt *p);
-
 static int my_set_echocanceller(void *pvt, int enable)
 {
 	struct dahdi_pvt *p = pvt;
@@ -3569,7 +3566,6 @@
 	ast_mutex_unlock(&p->lock);
 }
 
-static void dahdi_enable_ec(struct dahdi_pvt *p);
 static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
 {
 	struct dahdi_pvt *p = NULL;
@@ -4418,7 +4414,7 @@
 	ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
 }
 
-static void dahdi_enable_ec(struct dahdi_pvt *p)
+void dahdi_enable_ec(struct dahdi_pvt *p)
 {
 	int res;
 	if (!p)
@@ -4490,7 +4486,7 @@
 	}
 }
 
-static void dahdi_disable_ec(struct dahdi_pvt *p)
+void dahdi_disable_ec(struct dahdi_pvt *p)
 {
 	int res;
 
@@ -6210,7 +6206,7 @@
 	return res;
 }
 
-static void disable_dtmf_detect(struct dahdi_pvt *p)
+void disable_dtmf_detect(struct dahdi_pvt *p)
 {
 	int val = 0;
 
@@ -6224,7 +6220,7 @@
 	}
 }
 
-static void enable_dtmf_detect(struct dahdi_pvt *p)
+void enable_dtmf_detect(struct dahdi_pvt *p)
 {
 	int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
 
@@ -7043,20 +7039,21 @@
 
 		ast_channel_unlock(c0);
 		ast_channel_unlock(c1);
+
 		ms = ast_remaining_ms(start, timeoutms);
-		if (!ms ||
-			(op0 != p0) ||
-			(op1 != p1) ||
-			(ofd0 != ast_channel_fd(c0, 0)) ||
-			(ofd1 != ast_channel_fd(c1, 0)) ||
-			(p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != ast_channel_state(p0->subs[SUB_REAL].owner))) ||
-			(p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != ast_channel_state(p1->subs[SUB_REAL].owner))) ||
-			(oc0 != p0->owner) ||
-			(oc1 != p1->owner) ||
-			(t0 != p0->subs[SUB_REAL].inthreeway) ||
-			(t1 != p1->subs[SUB_REAL].inthreeway) ||
-			(oi0 != i0) ||
-			(oi1 != i1)) {
+		if (!ms ||/* Did we timeout? */
+			(op0 != p0) ||/* Did c0 get masqueraded or PRI changed associated B channel? */
+			(op1 != p1) ||/* Did c1 get masqueraded or PRI changed associated B channel? */
+			(ofd0 != ast_channel_fd(c0, 0)) ||/* Did c0 file descriptor change? (This is a redundant test with masquerade and active owner change) */
+			(ofd1 != ast_channel_fd(c1, 0)) ||/* Did c1 file descriptor change? (This is a redundant test with masquerade and active owner change) */
+			(p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != ast_channel_state(p0->subs[SUB_REAL].owner))) ||/* Did c0 state change? i.e. Did it stop ringing? */
+			(p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != ast_channel_state(p1->subs[SUB_REAL].owner))) ||/* Did c1 state chagne? i.e. Did it stop ringing? */
+			(oc0 != p0->owner) ||/* Did the p0 active owner change? */
+			(oc1 != p1->owner) ||/* Did the p1 active owner change? */
+			(t0 != p0->subs[SUB_REAL].inthreeway) ||/* Did the p0 three way call status change? */
+			(t1 != p1->subs[SUB_REAL].inthreeway) ||/* Did the p1 three way call status change? */
+			(oi0 != i0) ||/* Did the owner index change? */
+			(oi1 != i1)) {/* Did the owner index change? */
 			ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
 				op0->channel, oi0, op1->channel, oi1);
 			res = AST_BRIDGE_RETRY;

Modified: team/rmudgett/native_dahdi/channels/chan_dahdi.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/native_dahdi/channels/chan_dahdi.h?view=diff&rev=394277&r1=394276&r2=394277
==============================================================================
--- team/rmudgett/native_dahdi/channels/chan_dahdi.h (original)
+++ team/rmudgett/native_dahdi/channels/chan_dahdi.h Fri Jul 12 21:57:43 2013
@@ -794,6 +794,12 @@
 #define dahdi_get_index(ast, p, nullok)	_dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
 int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line);
 
+void disable_dtmf_detect(struct dahdi_pvt *p);
+void enable_dtmf_detect(struct dahdi_pvt *p);
+
+void dahdi_enable_ec(struct dahdi_pvt *p);
+void dahdi_disable_ec(struct dahdi_pvt *p);
+
 /* ------------------------------------------------------------------- */
 
 #if defined(__cplusplus) || defined(c_plusplus)

Modified: team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c?view=diff&rev=394277&r1=394276&r2=394277
==============================================================================
--- team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c (original)
+++ team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c Fri Jul 12 21:57:43 2013
@@ -34,10 +34,10 @@
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
+#include "../sig_analog.h"
 #if defined(HAVE_PRI)
 #include "../sig_pri.h"
 #endif	/* defined(HAVE_PRI) */
-#include "../sig_analog.h"
 #include "../chan_dahdi.h"
 
 #include "asterisk/astobj.h"
@@ -51,7 +51,22 @@
 
 static const struct ast_channel_tech *dahdi_tech;
 
-struct native_bridge_pvt {
+struct native_pvt_chan {
+	/*! Original private. */
+	struct dahdi_pvt *pvt;
+	/*! Original private owner. */
+	struct ast_channel *owner;
+	/*! Original owner index. */
+	int index;
+	/*! Original file descriptor 0. */
+	int fd0;
+	/*! Original channel state. */
+	int state;
+	/*! Original inthreeway. */
+	unsigned int inthreeway:1;
+};
+
+struct native_pvt_bridge {
 	/*! Master channel in the native bridge. */
 	struct dahdi_pvt *master;
 	/*! Slave channel in the native bridge. */
@@ -60,6 +75,16 @@
 	unsigned int saw_start:1;
 	/*! TRUE if the channels are connected in a conference. */
 	unsigned int connected:1;
+#if defined(HAVE_PRI) && defined(PRI_2BCT)
+	/*!
+	 * \brief TRUE if tried to eliminate possible PRI tromboned call.
+	 *
+	 * \note A tromboned call uses two B channels of the same ISDN
+	 * span.  One leg comes into Asterisk, the other leg goes out of
+	 * Asterisk, and Asterisk is natively bridging the two legs.
+	 */
+	unsigned int tried_trombone_removal:1;
+#endif	/* defined(HAVE_PRI) && defined(PRI_2BCT) */
 };
 
 /*!
@@ -75,14 +100,17 @@
  */
 static int native_bridge_create(struct ast_bridge *bridge)
 {
-	struct native_bridge_pvt *tech_pvt;
+	struct native_pvt_bridge *tech_pvt;
 
 	ast_assert(!bridge->tech_pvt);
 
-	tech_pvt = ao2_alloc_options(sizeof(*tech_pvt), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	tech_pvt = ast_calloc(1, sizeof(*tech_pvt));
+	if (!tech_pvt) {
+		return -1;
+	}
+
 	bridge->tech_pvt = tech_pvt;
-
-	return tech_pvt ? 0 : -1;
+	return 0;
 }
 
 /*!
@@ -94,11 +122,154 @@
  */
 static void native_bridge_destroy(struct ast_bridge *bridge)
 {
-	struct native_bridge_pvt *tech_pvt;
+	struct native_pvt_bridge *tech_pvt;
 
 	tech_pvt = bridge->tech_pvt;
 	bridge->tech_pvt = NULL;
-	ao2_cleanup(tech_pvt);
+	ast_free(tech_pvt);
+}
+
+/*!
+ * \internal
+ * \brief Stop native bridging activity.
+ * \since 12.0.0
+ *
+ * \param bridge What to operate upon.
+ *
+ * \return Nothing
+ *
+ * \note On entry, bridge is already locked.
+ */
+static void native_stop(struct ast_bridge *bridge)
+{
+	/*! \todo BUGBUG native_stop() not written */
+}
+
+/*!
+ * \internal
+ * \brief Request to stop native bridging activity.
+ * \since 12.0.0
+ *
+ * \param bridge What to operate upon.
+ *
+ * \return Nothing
+ *
+ * \note On entry, bridge is already locked.
+ */
+static void native_request_stop(struct ast_bridge *bridge)
+{
+	struct native_pvt_bridge *tech_pvt;
+
+	ast_assert(bridge->tech_pvt != NULL);
+
+	tech_pvt = bridge->tech_pvt;
+	if (!tech_pvt->connected) {
+		return;
+	}
+
+	/* Now to actually stop the bridge. */
+	native_stop(bridge);
+}
+
+/*!
+ * \internal
+ * \brief Start native bridging activity.
+ * \since 12.0.0
+ *
+ * \param bridge What to operate upon.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.  Could not start the bridge.
+ *
+ * \note On entry, bridge may or may not already be locked.
+ * However, it can be accessed as if it were locked.
+ */
+static int native_start(struct ast_bridge *bridge)
+{
+	/*
+	 * Check things that can change on the privates while in native
+	 * bridging and cause native to not activate.
+	 */
+#if 0 //BUGBUG
+	if (dahdi_get_index(chan, pvt, 0) < 0) {
+		/* This is something that can change while in native bridge. */
+	}
+#if defined(HAVE_PRI)
+	if (dahdi_sig_pri_lib_handles(pvt->sig)
+		&& ((struct sig_pri_chan *) pvt->sig_pvt)->no_b_channel) {
+		/*
+		 * PRI nobch channels (hold and call waiting) are equivalent to
+		 * pseudo channels and cannot be done here.
+		 */
+	}
+#endif	/* defined(HAVE_PRI) */
+#endif
+
+	/*! \todo BUGBUG native_start() not written */
+	return -1;
+}
+
+/*!
+ * \internal
+ * \brief Request to start native bridging activity.
+ * \since 12.0.0
+ *
+ * \param bridge What to operate upon.
+ *
+ * \return Nothing
+ *
+ * \note On entry, bridge may or may not already be locked.
+ * However, it can be accessed as if it were locked.
+ */
+static void native_request_start(struct ast_bridge *bridge)
+{
+	struct native_pvt_bridge *tech_pvt;
+	struct ast_bridge_channel *cur;
+
+	ast_assert(bridge->tech_pvt != NULL);
+
+	tech_pvt = bridge->tech_pvt;
+
+	if (bridge->num_channels != 2 || !tech_pvt->saw_start || tech_pvt->connected) {
+		return;
+	}
+	AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
+		if (cur->suspended || !cur->tech_pvt) {
+			return;
+		}
+	}
+
+	/* Actually try starting the native bridge. */
+	if (native_start(bridge)) {
+		return;
+	}
+
+#if defined(HAVE_PRI) && defined(PRI_2BCT)
+	if (!tech_pvt->tried_trombone_removal) {
+		struct dahdi_pvt *master;
+		struct dahdi_pvt *slave;
+
+		tech_pvt->tried_trombone_removal = 1;
+
+		master = tech_pvt->master;
+		slave = tech_pvt->slave;
+		if (master->pri && master->pri == slave->pri && master->pri->transfer) {
+			q931_call *q931_master;
+			q931_call *q931_slave;
+
+			/* Try to eliminate the tromboned call. */
+			ast_mutex_lock(&master->pri->lock);
+			ast_assert(dahdi_sig_pri_lib_handles(master->sig));
+			ast_assert(dahdi_sig_pri_lib_handles(slave->sig));
+			q931_master = ((struct sig_pri_chan *) (master->sig_pvt))->call;
+			q931_slave = ((struct sig_pri_chan *) (slave->sig_pvt))->call;
+			if (q931_master && q931_slave) {
+				pri_channel_bridge(q931_master, q931_slave);
+			}
+			ast_mutex_unlock(&master->pri->lock);
+		}
+	}
+#endif	/* defined(HAVE_PRI) && defined(PRI_2BCT) */
 }
 
 /*!
@@ -114,15 +285,15 @@
  */
 static int native_bridge_start(struct ast_bridge *bridge)
 {
-	struct native_bridge_pvt *tech_pvt;
+	struct native_pvt_bridge *tech_pvt;
 
 	ast_assert(bridge->tech_pvt != NULL);
 
 	tech_pvt = bridge->tech_pvt;
 	tech_pvt->saw_start = 1;
 
-	/*! \todo BUGBUG native_bridge_start() not written */
-	return -1;
+	native_request_start(bridge);
+	return 0;
 }
 
 /*!
@@ -134,14 +305,15 @@
  */
 static void native_bridge_stop(struct ast_bridge *bridge)
 {
-	struct native_bridge_pvt *tech_pvt;
-
-	ast_assert(bridge->tech_pvt != NULL);
+	struct native_pvt_bridge *tech_pvt;
 
 	tech_pvt = bridge->tech_pvt;
+	if (!tech_pvt) {
+		return;
+	}
+
 	tech_pvt->saw_start = 0;
-
-	/*! \todo BUGBUG native_bridge_stop() not written */
+	native_request_stop(bridge);
 }
 
 /*!
@@ -156,8 +328,24 @@
  */
 static int native_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
-	/*! \todo BUGBUG native_bridge_join() not written */
-	return -1;
+	struct native_pvt_chan *tech_pvt;
+
+	ast_assert(!bridge_channel->tech_pvt);
+
+	tech_pvt = ast_calloc(1, sizeof(*tech_pvt));
+	if (!tech_pvt) {
+		return -1;
+	}
+
+/* BUGBUG is the following true about DAHDI channels? */
+	/*
+	 * Since this bridge only serves DAHDI channels, we don't need
+	 * to make them compatible.
+	 */
+
+	bridge_channel->tech_pvt = tech_pvt;
+	native_request_start(bridge);
+	return 0;
 }
 
 /*!
@@ -169,7 +357,13 @@
  */
 static void native_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
-	/*! \todo BUGBUG native_bridge_leave() not written */
+	struct native_pvt_chan *tech_pvt;
+
+	native_request_stop(bridge);
+
+	tech_pvt = bridge_channel->tech_pvt;
+	bridge_channel->tech_pvt = NULL;
+	ast_free(tech_pvt);
 }
 
 /*!
@@ -181,7 +375,7 @@
  */
 static void native_bridge_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
-	/*! \todo BUGBUG native_bridge_suspend() not written */
+	native_request_stop(bridge);
 }
 
 /*!
@@ -193,7 +387,7 @@
  */
 static void native_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
-	/*! \todo BUGBUG native_bridge_unsuspend() not written */
+	native_request_start(bridge);
 }
 
 /*!
@@ -209,7 +403,7 @@
 {
 	struct ast_channel *chan = bridge_channel->chan;
 	struct dahdi_pvt *pvt;
-	int is_compatible;
+	int is_capable;
 
 	if (ao2_container_count(bridge_channel->features->dtmf_hooks)) {
 		ast_debug(2, "Channel '%s' has DTMF hooks.\n", ast_channel_name(chan));
@@ -240,37 +434,23 @@
 		return 0;
 	}
 
-	is_compatible = 1;
+	is_capable = 1;
 	ast_mutex_lock(&pvt->lock);
 
-	if (dahdi_get_index(chan, pvt, 0) < 0) {
-		is_compatible = 0;
-	} else if (pvt->callwaiting && pvt->callwaitingcallerid) {
+	if (pvt->callwaiting && pvt->callwaitingcallerid) {
 		/*
 		 * Call Waiting Caller ID requires DTMF detection to know if it
 		 * can send the CID spill.
 		 */
 		ast_debug(2, "Channel '%s' has call waiting caller ID enabled.\n",
 			ast_channel_name(chan));
-		is_compatible = 0;
-	}
-#if defined(HAVE_PRI)
-	else if (dahdi_sig_pri_lib_handles(pvt->sig)
-		&& ((struct sig_pri_chan *) pvt->sig_pvt)->no_b_channel) {
-		/*
-		 * PRI nobch channels (hold and call waiting) are equivalent to
-		 * pseudo channels and cannot be done here.
-		 */
-		ast_debug(2, "Channel '%s' has no B channel.\n",
-			ast_channel_name(chan));
-		is_compatible = 0;
-	}
-#endif	/* defined(HAVE_PRI) */
+		is_capable = 0;
+	}
 
 	ast_mutex_unlock(&pvt->lock);
 	ast_channel_unlock(chan);
 
-	return is_compatible;
+	return is_capable;
 }
 
 /*!
@@ -288,28 +468,101 @@
 {
 	struct ast_bridge_channel *cur;
 
-	/* We require two channels before even considering native bridging */
+	/* We require two channels before even considering native bridging. */
 	if (bridge->num_channels != 2) {
-		ast_debug(1, "Bridge '%s' cannot use native DAHDI.  Two channels are required.\n",
+		ast_debug(1, "Bridge %s: Cannot use native DAHDI.  Must have two channels.\n",
 			bridge->uniqueid);
 		return 0;
 	}
 
 	AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
 		if (!native_bridge_is_capable(cur)) {
-			ast_debug(1, "Bridge '%s' cannot use native DAHDI.  Channel '%s' not compatible.\n",
+			ast_debug(1, "Bridge %s: Cannot use native DAHDI.  Channel '%s' not compatible.\n",
+				bridge->uniqueid, ast_channel_name(cur->chan));
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+/*!
+ * \internal
+ * \brief Check if something changed on the channel.
+ * \since 12.0.0
+ *
+ * \param bridge_channel What to operate upon.
+ *
+ * \retval 0 Nothing changed.
+ * \retval -1 Something changed.
+ *
+ * \note On entry, bridge_channel->bridge is already locked.
+ */
+static int native_chan_changed(struct ast_bridge_channel *bridge_channel)
+{
+	struct native_pvt_chan *tech_pvt;
+	struct ast_channel *chan;
+	struct dahdi_pvt *pvt;
+	int idx = -1;
+
+	ast_assert(bridge_channel->tech_pvt != NULL);
+
+	tech_pvt = bridge_channel->tech_pvt;
+
+	chan = bridge_channel->chan;
+	ast_channel_lock(chan);
+	pvt = ast_channel_tech_pvt(chan);
+	if (tech_pvt->pvt == pvt) {
+		idx = dahdi_get_index(chan, pvt, 1);
+	}
+	ast_channel_unlock(chan);
+
+	if (/* Did chan get masqueraded or PRI change associated B channel? */
+		tech_pvt->pvt != pvt
+		/* Did the pvt active owner change? */
+		|| tech_pvt->owner != pvt->owner
+		/* Did the pvt three way call status change? */
+		|| tech_pvt->inthreeway != pvt->subs[SUB_REAL].inthreeway
+		/* Did the owner index change? */
+		|| tech_pvt->index != idx
+		/*
+		 * Did chan file descriptor change? (This seems redundant with
+		 * masquerade and active owner change checks.)
+		 */
+		|| tech_pvt->fd0 != ast_channel_fd(chan, 0)
+		/* Did chan state change? i.e. Did it stop ringing? */
+		|| (pvt->subs[SUB_REAL].owner
+			&& tech_pvt->state > -1
+			&& tech_pvt->state != ast_channel_state(pvt->subs[SUB_REAL].owner))) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Check if something changed on the bridge channels.
+ * \since 12.0.0
+ *
+ * \param bridge What to operate upon.
+ *
+ * \retval 0 Nothing changed.
+ * \retval -1 Something changed.
+ *
+ * \note On entry, bridge is already locked.
+ */
+static int native_bridge_changed(struct ast_bridge *bridge)
+{
+	struct ast_bridge_channel *cur;
+
+	AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
+		if (native_chan_changed(cur)) {
+			ast_debug(1, "Bridge %s: Something changed on channel '%s'.\n",
 				bridge->uniqueid, ast_channel_name(cur->chan));
 			return -1;
 		}
 	}
-
-/*
- * BUGBUG if we are the current bridge tech and bridge is active, check if the pvts still match.
- *
- * A masquerade has changed one of the channels on us.  We need
- * to generate an ERROR message and destroy the bridge.
- */
-
 	return 0;
 }
 
@@ -327,6 +580,34 @@
  */
 static int native_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 {
+	struct native_pvt_bridge *tech_pvt;
+
+	/*
+	 * When we are not native bridged by DAHDI, we are like a normal
+	 * 1-1 bridge.
+	 */
+
+	ast_assert(bridge->tech_pvt != NULL);
+
+	/* Recheck native bridging validity. */
+	tech_pvt = bridge->tech_pvt;
+	if (tech_pvt->connected) {
+		if (native_bridge_changed(bridge)) {
+			native_stop(bridge);
+			native_request_start(bridge);
+		}
+	} else {
+		/* Don't try to start native mode on media frames. */
+		switch (frame->frametype) {
+		case AST_FRAME_VOICE:
+		case AST_FRAME_VIDEO:
+			break;
+		default:
+			native_request_start(bridge);
+			break;
+		}
+	}
+
 	return ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
 }
 
@@ -377,6 +658,12 @@
 	if (!native_bridge.format_capabilities) {
 		return -1;
 	}
+/*
+ * BUGBUG may not need to specify specific formats supported by DAHDI.
+ *
+ * This is only used to make channels compatible with the bridge
+ * itself in multi-party bridges.
+ */
 	ast_format_cap_add(native_bridge.format_capabilities, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
 	ast_format_cap_add(native_bridge.format_capabilities, ast_format_set(&format, AST_FORMAT_ULAW, 0));
 	ast_format_cap_add(native_bridge.format_capabilities, ast_format_set(&format, AST_FORMAT_ALAW, 0));

Modified: team/rmudgett/native_dahdi/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/native_dahdi/main/bridging.c?view=diff&rev=394277&r1=394276&r2=394277
==============================================================================
--- team/rmudgett/native_dahdi/main/bridging.c (original)
+++ team/rmudgett/native_dahdi/main/bridging.c Fri Jul 12 21:57:43 2013
@@ -375,6 +375,10 @@
 		/* Drop non-deferable frames when suspended. */
 		return 0;
 	}
+	if (fr->frametype == AST_FRAME_NULL) {
+		/* "Accept" the frame and discard it. */
+		return 0;
+	}
 
 	dup = ast_frdup(fr);
 	if (!dup) {
@@ -426,6 +430,11 @@
 {
 	struct ast_bridge_channel *cur;
 	int not_written = -1;
+
+	if (frame->frametype == AST_FRAME_NULL) {
+		/* "Accept" the frame and discard it. */
+		return 0;
+	}
 
 	AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
 		if (cur == bridge_channel) {
@@ -1254,10 +1263,6 @@
 		return;
 	}
 	switch (frame->frametype) {
-	case AST_FRAME_NULL:
-		/* Just discard it. */
-		ast_frfree(frame);
-		return;
 	case AST_FRAME_CONTROL:
 		switch (frame->subclass.integer) {
 		case AST_CONTROL_HANGUP:




More information about the asterisk-commits mailing list