[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