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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jul 11 19:33:48 CDT 2013


Author: rmudgett
Date: Thu Jul 11 19:33:46 2013
New Revision: 394178

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394178
Log:
Implement the create, destroy, and compatible tech callbacks.

Modified:
    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

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=394178&r1=394177&r2=394178
==============================================================================
--- team/rmudgett/native_dahdi/channels/chan_dahdi.c (original)
+++ team/rmudgett/native_dahdi/channels/chan_dahdi.c Thu Jul 11 19:33:46 2013
@@ -3253,8 +3253,7 @@
 /*! Round robin search locations. */
 static struct dahdi_pvt *round_robin[32];
 
-#define dahdi_get_index(ast, p, nullok)	_dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
-static int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
+int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
 {
 	int res;
 	if (p->subs[SUB_REAL].owner == ast)
@@ -4363,7 +4362,7 @@
 	return 0;
 }
 
-static int update_conf(struct dahdi_pvt *p)
+static void update_conf(struct dahdi_pvt *p)
 {
 	int needconf = 0;
 	int x;
@@ -4416,7 +4415,6 @@
 		p->confno = -1;
 	}
 	ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
-	return 0;
 }
 
 static void dahdi_enable_ec(struct dahdi_pvt *p)

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=394178&r1=394177&r2=394178
==============================================================================
--- team/rmudgett/native_dahdi/channels/chan_dahdi.h (original)
+++ team/rmudgett/native_dahdi/channels/chan_dahdi.h Thu Jul 11 19:33:46 2013
@@ -791,6 +791,9 @@
 	return 1;
 }
 
+#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);
+
 /* ------------------------------------------------------------------- */
 
 #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=394178&r1=394177&r2=394178
==============================================================================
--- team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c (original)
+++ team/rmudgett/native_dahdi/channels/dahdi/bridge_native_dahdi.c Thu Jul 11 19:33:46 2013
@@ -37,69 +37,294 @@
 #if defined(HAVE_PRI)
 #include "../sig_pri.h"
 #endif	/* defined(HAVE_PRI) */
-
 #include "../sig_analog.h"
-
 #include "../chan_dahdi.h"
+
 #include "asterisk/astobj.h"
 #include "bridge_native_dahdi.h"
 #include "asterisk/bridging.h"
 #include "asterisk/bridging_technology.h"
 #include "asterisk/frame.h"
+#include "asterisk/audiohook.h"
 
 /* ------------------------------------------------------------------- */
 
 static const struct ast_channel_tech *dahdi_tech;
 
+struct native_bridge_pvt {
+	/*! Master channel in the native bridge. */
+	struct dahdi_pvt *master;
+	/*! Slave channel in the native bridge. */
+	struct dahdi_pvt *slave;
+	/*! TRUE if the bridge can start when ready. */
+	unsigned int saw_start:1;
+	/*! TRUE if the channels are connected in a conference. */
+	unsigned int connected:1;
+};
+
+/*!
+ * \internal
+ * \brief Create a bridge technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \note On entry, bridge may or may not already be locked.
+ * However, it can be accessed as if it were locked.
+ */
 static int native_bridge_create(struct ast_bridge *bridge)
 {
-	/*! \todo BUGBUG native_bridge_create() not written */
-	return -1;
-}
-
+	struct native_bridge_pvt *tech_pvt;
+
+	ast_assert(!bridge->tech_pvt);
+
+	tech_pvt = ao2_alloc_options(sizeof(*tech_pvt), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	bridge->tech_pvt = tech_pvt;
+
+	return tech_pvt ? 0 : -1;
+}
+
+/*!
+ * \internal
+ * \brief Destroy a bridging technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \note On entry, bridge must NOT be locked.
+ */
+static void native_bridge_destroy(struct ast_bridge *bridge)
+{
+	struct native_bridge_pvt *tech_pvt;
+
+	tech_pvt = bridge->tech_pvt;
+	bridge->tech_pvt = NULL;
+	ao2_cleanup(tech_pvt);
+}
+
+/*!
+ * \internal
+ * \brief Request a bridge technology instance start operations.
+ * \since 12.0.0
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \note On entry, bridge may or may not already be locked.
+ * However, it can be accessed as if it were locked.
+ */
 static int native_bridge_start(struct ast_bridge *bridge)
 {
+	struct native_bridge_pvt *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;
 }
 
+/*!
+ * \internal
+ * \brief Request a bridge technology instance stop in preparation for being destroyed.
+ * \since 12.0.0
+ *
+ * \note On entry, bridge is already locked.
+ */
 static void native_bridge_stop(struct ast_bridge *bridge)
 {
+	struct native_bridge_pvt *tech_pvt;
+
+	ast_assert(bridge->tech_pvt != NULL);
+
+	tech_pvt = bridge->tech_pvt;
+	tech_pvt->saw_start = 0;
+
 	/*! \todo BUGBUG native_bridge_stop() not written */
 }
 
-static void native_bridge_destroy(struct ast_bridge *bridge)
-{
-	/*! \todo BUGBUG native_bridge_destroy() not written */
-}
-
+/*!
+ * \internal
+ * \brief Add a channel to a bridging technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \note On entry, bridge is already locked.
+ */
 static int native_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
 	/*! \todo BUGBUG native_bridge_join() not written */
 	return -1;
 }
 
+/*!
+ * \internal
+ * \brief Remove a channel from a bridging technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \note On entry, bridge is already locked.
+ */
 static void native_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
 	/*! \todo BUGBUG native_bridge_leave() not written */
 }
 
+/*!
+ * \internal
+ * \brief Suspend a channel on a bridging technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \note On entry, bridge is already locked.
+ */
 static void native_bridge_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
 	/*! \todo BUGBUG native_bridge_suspend() not written */
 }
 
+/*!
+ * \internal
+ * \brief Unsuspend a channel on a bridging technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \note On entry, bridge is already locked.
+ */
 static void native_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
 	/*! \todo BUGBUG native_bridge_unsuspend() not written */
 }
 
+/*!
+ * \internal
+ * \brief Check if channel is compatible.
+ * \since 12.0.0
+ *
+ * \param bridge_channel Is this channel compatible.
+ *
+ * \retval TRUE if channel is compatible with native DAHDI bridge.
+ */
+static int native_bridge_is_capable(struct ast_bridge_channel *bridge_channel)
+{
+	struct ast_channel *chan = bridge_channel->chan;
+	struct dahdi_pvt *pvt;
+	int is_compatible;
+
+	if (ao2_container_count(bridge_channel->features->dtmf_hooks)) {
+		ast_debug(2, "Channel '%s' has DTMF hooks.\n", ast_channel_name(chan));
+		return 0;
+	}
+
+	ast_channel_lock(chan);
+
+	if (dahdi_tech != ast_channel_tech(chan)) {
+		ast_debug(2, "Channel '%s' is not %s.\n",
+			ast_channel_name(chan), dahdi_tech->type);
+		ast_channel_unlock(chan);
+		return 0;
+	}
+	if (ast_channel_monitor(chan)
+		|| (ast_channel_audiohooks(chan)
+			&& !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan)))
+		|| !ast_framehook_list_contains_no_active(ast_channel_framehooks(chan))) {
+		ast_debug(2, "Channel '%s' has an active monitor, audiohook, or framehook.\n",
+			ast_channel_name(chan));
+		ast_channel_unlock(chan);
+		return 0;
+	}
+	pvt = ast_channel_tech_pvt(chan);
+	if (!pvt || !pvt->sig) {
+		/* No private or signaling is for a pseudo channel. */
+		ast_channel_unlock(chan);
+		return 0;
+	}
+
+	is_compatible = 1;
+	ast_mutex_lock(&pvt->lock);
+
+	if (dahdi_get_index(chan, pvt, 0) < 0) {
+		is_compatible = 0;
+	} else 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) */
+
+	ast_mutex_unlock(&pvt->lock);
+	ast_channel_unlock(chan);
+
+	return is_compatible;
+}
+
+/*!
+ * \internal
+ * \brief Check if a bridge is compatible with the bridging technology.
+ * \since 12.0.0
+ *
+ * \retval 0 if not compatible
+ * \retval non-zero if compatible
+ *
+ * \note On entry, bridge may or may not already be locked.
+ * However, it can be accessed as if it were locked.
+ */
 static int native_bridge_compatible(struct ast_bridge *bridge)
 {
-	/*! \todo BUGBUG native_bridge_compatible() not written */
-	return -1;
-}
-
+	struct ast_bridge_channel *cur;
+
+	/* 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",
+			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",
+				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;
+}
+
+/*!
+ * \internal
+ * \brief Write a frame into the bridging technology instance for a bridge.
+ * \since 12.0.0
+ *
+ * \note The bridge must be tolerant of bridge_channel being NULL.
+ *
+ * \retval 0 Frame accepted into the bridge.
+ * \retval -1 Frame needs to be deferred.
+ *
+ * \note On entry, bridge is already locked.
+ */
 static int native_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 {
 	return ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);




More information about the asterisk-commits mailing list