[asterisk-commits] moy: branch moy/dahdi-tap-1.6.2 r219809 - /team/moy/dahdi-tap-1.6.2/channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Sep 22 11:52:09 CDT 2009
Author: moy
Date: Tue Sep 22 11:52:05 2009
New Revision: 219809
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=219809
Log:
inital code to record calls on tapped PRI links
Modified:
team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c
Modified: team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c?view=diff&rev=219809&r1=219808&r2=219809
==============================================================================
--- team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c (original)
+++ team/moy/dahdi-tap-1.6.2/channels/chan_dahdi.c Tue Sep 22 11:52:05 2009
@@ -106,6 +106,8 @@
#include "asterisk/event.h"
#include "asterisk/devicestate.h"
#include "asterisk/paths.h"
+#include "asterisk/pbx.h"
+#include "asterisk/features.h"
/*** DOCUMENTATION
<application name="DAHDISendKeypadFacility" language="en_US">
@@ -4130,6 +4132,17 @@
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_PRI)
+static struct dahdi_pri *pri_find_by_span(int span)
+{
+ int x;
+ for (x = 0; x < NUM_SPANS; x++) {
+ if (pris[x].span == span) {
+ return &pris[x];
+ }
+ }
+ return NULL;
+}
+
static int pri_find_dchan(struct dahdi_pri *pri)
{
int oldslot = -1;
@@ -12341,6 +12354,199 @@
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_PRI)
+struct dahdi_pri_bridge_info
+{
+ struct ast_channel *chan;
+ struct ast_channel *peer;
+};
+
+static void *pri_bridge_call(void *args)
+{
+ struct ast_bridge_config bconfig = { { 0, }, };
+ int ret = 0;
+ struct dahdi_pri_bridge_info *binfo = args;
+ ast_log(LOG_NOTICE, "Bridging PRI channels %s and %s\n", binfo->chan->name, binfo->peer->name);
+ ret = ast_bridge_call(binfo->chan, binfo->peer, &bconfig);
+ ast_log(LOG_NOTICE, "Done Bridging of PRI channels %s and %s\n", binfo->chan->name, binfo->chan->name);
+ ast_hangup(binfo->chan);
+ ast_hangup(binfo->peer);
+ ast_free(binfo);
+ return NULL;
+}
+
+static void launch_pri_bridge_thread(struct ast_channel *c1, struct ast_channel *c2)
+{
+ struct dahdi_pri_bridge_info *binfo = NULL;
+ pthread_t thread;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ binfo = ast_calloc(1, sizeof(*binfo));
+ if (!binfo) {
+ ast_log(LOG_WARNING, "Failed to create PRI bridge info structure\n");
+ return;
+ }
+
+ binfo->chan = c1;
+ binfo->peer = c2;
+ if (ast_pthread_create_background(&thread, &attr, pri_bridge_call, binfo)) {
+ ast_log(LOG_WARNING, "Failed to create PRI bridge thread\n");
+ return;
+ }
+
+ pthread_attr_destroy(&attr);
+}
+
+static void handle_pri_passive_event(struct dahdi_pri *pri, pri_event *e)
+{
+ int chanpos;
+ struct ast_app *app = NULL;
+ struct ast_channel *c = NULL;
+ struct ast_channel *peer = NULL;
+ int peerspan = !(pri->span % 2) ? (pri->span - 1) : (pri->span + 1);
+ struct dahdi_pri *peerpri = pri_find_by_span(peerspan);
+ if (!peerpri) {
+ ast_log(LOG_WARNING, "Ignoring passive PRI event on span %d, no peer span found\n", pri->span);
+ return;
+ }
+ /* XXX TODO: chanpos is calculated for both pri and peerpri, is it needed or will it be always the same chanpos for both? XXX */
+ switch (e->e) {
+
+ case PRI_EVENT_RING:
+ ast_log(LOG_NOTICE, "Ring on channel %d of span %d\n", e->ring.channel, pri->span);
+ break;
+
+ case PRI_EVENT_PROGRESS:
+ ast_log(LOG_NOTICE, "Progress on channel %d of span %d\n", e->proceeding.channel, pri->span);
+ break;
+
+ case PRI_EVENT_PROCEEDING:
+ ast_log(LOG_NOTICE, "Proceeding on channel %d of span %d\n", e->proceeding.channel, pri->span);
+ /* at this point we should know the real b chan that will be used */
+ chanpos = pri_find_principle(pri, e->proceeding.channel);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Proceeding requested on odd/unavailable channel number %d/%d on span %d\n",
+ PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
+ break;
+ }
+
+ /* XXX FIXME: Law must be taken from PRI_EVENT_RING, I think, the same for capabilities XXX */
+ c = dahdi_new(pri->pvts[chanpos], AST_STATE_RINGING, 0, SUB_REAL, DAHDI_LAW_MULAW, AST_TRANS_CAP_SPEECH);
+ if (!c) {
+ ast_log(LOG_WARNING, "Failed to create channel for call on channel %d/%d on span %d\n",
+ PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
+ break;
+ }
+ pri->pvts[chanpos]->owner = c;
+
+ /* now get the bridged peer pvt */
+ chanpos = pri_find_principle(peerpri, e->proceeding.channel);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Proceeding requested on odd/unavailable channel number %d/%d on peer span %d\n",
+ PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), peerpri->span);
+ break;
+ }
+ c = dahdi_new(peerpri->pvts[chanpos], AST_STATE_RINGING, 0, SUB_REAL, DAHDI_LAW_MULAW, AST_TRANS_CAP_SPEECH);
+ if (!c) {
+ ast_log(LOG_WARNING, "Failed to create channel for call on channel %d/%d on peer span %d\n",
+ PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), peerpri->span);
+ break;
+ }
+ peerpri->pvts[chanpos]->owner = c;
+
+ break;
+
+ case PRI_EVENT_ANSWER:
+ ast_log(LOG_NOTICE, "Answer on channel %d of span %d\n", e->proceeding.channel, pri->span);
+ chanpos = pri_find_principle(pri, e->answer.channel);
+ if (!pri->pvts[chanpos]->owner) {
+ ast_log(LOG_WARNING, "No owner on answer in channel number %d/%d on span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Answer requested on odd/unavailable channel number %d/%d on span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+ c = pri->pvts[chanpos]->owner;
+ ast_setstate(c, AST_STATE_UP);
+
+ /* Now launch the monitor in the first channel */
+ app = pbx_findapp("MixMonitor");
+ if (!app) {
+ ast_log(LOG_WARNING, "Failed to find mix monitor application for channel number %d/%d on span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+ if (pbx_exec(pri->pvts[chanpos]->owner, app, "/tmp/sangoma_monitor.ulaw")) {
+ ast_log(LOG_WARNING, "Failed to launch mix monitor in channel number %d/%d on span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+
+ chanpos = pri_find_principle(peerpri, e->answer.channel);
+ if (!peerpri->pvts[chanpos]->owner) {
+ ast_log(LOG_WARNING, "No owner on answer in channel number %d/%d on peer span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), peerpri->span);
+ break;
+ }
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Answer requested on odd/unavailable channel number %d/%d on peer span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+ peer = peerpri->pvts[chanpos]->owner;
+ ast_setstate(peer, AST_STATE_UP);
+
+
+ /* Now bridge them in their own thread */
+ launch_pri_bridge_thread(c, peer);
+ break;
+
+ case PRI_EVENT_HANGUP:
+ /* XXX TODO: Verify how the interal pri call struct will be freed XXX */
+
+ ast_log(LOG_NOTICE, "Hangup on channel %d of span %d\n", e->hangup.channel, pri->span);
+ chanpos = pri_find_principle(pri, e->hangup.channel);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Hangup requested on odd/unavailable channel number %d/%d on span %d\n",
+ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+ break;
+ }
+ if (!pri->pvts[chanpos]->owner) {
+ ast_log(LOG_WARNING, "No owner on hangup in channel number %d/%d on span %d\n",
+ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+ break;
+ }
+ ast_queue_hangup(pri->pvts[chanpos]->owner);
+
+ chanpos = pri_find_principle(peerpri, e->hangup.channel);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Hangup requested on odd/unavailable channel number %d/%d on peer span %d\n",
+ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), peerpri->span);
+ break;
+ }
+
+ if (!peerpri->pvts[chanpos]->owner) {
+ ast_log(LOG_WARNING, "No owner on hangup in channel number %d/%d on peer span %d\n",
+ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), peerpri->span);
+ break;
+ }
+ ast_queue_hangup(peerpri->pvts[chanpos]->owner);
+ break;
+
+ case PRI_EVENT_HANGUP_ACK:
+ ast_log(LOG_NOTICE, "Hangup ack on channel %d of span %d\n", e->hangup.channel, pri->span);
+ break;
+
+ default:
+ ast_log(LOG_NOTICE, "Ignoring passive event %s on span %d\n", pri_event2str(e->gen.e), pri->span);
+ break;
+ }
+}
+
static void *pri_dchannel(void *vpri)
{
struct dahdi_pri *pri = vpri;
@@ -12547,7 +12753,15 @@
ast_debug(1, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
} else if (fds[which].revents & POLLIN) {
+#ifdef CHAN_DAHDI_NORMAL
e = pri_check_event(pri->dchans[which]);
+#else
+ e = pri_read_event(pri->dchans[which]);
+ if (e) {
+ handle_pri_passive_event(pri, e);
+ e = NULL;
+ }
+#endif
}
if (e)
break;
More information about the asterisk-commits
mailing list