Revision: cc3bf447ceb7
Author:   unknown <yulian@Venera.(none)>
Date:     Fri Jan  4 07:17:31 2013
Log:      Completed OOB stage 2-3 - core path

http://code.google.com/p/mediaserver/source/detail?r=cc3bf447ceb7

Added:
/io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/rfc2833/DtmfInput.java /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/rfc2833/DtmfOutput.java
Modified:
 /client/jsr-309/tck/media/decreasingvolume-recorded.wav
 /client/jsr-309/tck/server.log
/core/src/main/java/org/mobicents/media/core/connections/BaseConnection.java /core/src/main/java/org/mobicents/media/core/connections/LocalConnectionImpl.java /core/src/main/java/org/mobicents/media/core/connections/RtpConnectionImpl.java /core/src/main/java/org/mobicents/media/core/endpoints/BaseMixerEndpointImpl.java /core/src/main/java/org/mobicents/media/core/endpoints/BaseSS7EndpointImpl.java /core/src/main/java/org/mobicents/media/core/endpoints/BaseSplitterEndpointImpl.java
 /core/src/main/java/org/mobicents/media/core/endpoints/MediaGroup.java
/core/src/test/java/org/mobicents/media/core/connections/MyTestConnection.java /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/LocalDataChannel.java /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/RTPDataChannel.java /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/sdp/AVProfile.java
 /io/ss7/src/main/java/org/mobicents/media/server/io/ss7/SS7DataChannel.java
/media-server-docs/sources-mobicents/src/main/resources/META-INF/MANIFEST.MF /media-server-docs/sources-mobicents/src/main/resources/META-INF/maven/org.mobicents.media.docs/mobicents-mms-docs-sources/pom.properties /resources/recorder/src/main/java/org/mobicents/media/server/impl/resource/audio/AudioRecorderImpl.java /resources/telephony/dtmf/src/main/java/org/mobicents/media/server/impl/resource/dtmf/DetectorImpl.java /resources/telephony/dtmf/src/main/java/org/mobicents/media/server/impl/resource/dtmf/GeneratorImpl.java

=======================================
--- /dev/null
+++ /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/rfc2833/DtmfInput.java Fri Jan 4 07:17:31 2013
@@ -0,0 +1,181 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.mobicents.media.server.impl.rtp.rfc2833;
+
+import org.mobicents.media.server.component.oob.OOBInput;
+import org.mobicents.media.server.scheduler.Scheduler;
+import org.mobicents.media.server.impl.rtp.RtpClock;
+import org.mobicents.media.server.impl.rtp.RtpPacket;
+import org.mobicents.media.server.impl.AbstractSource;
+import org.mobicents.media.server.spi.format.AudioFormat;
+import org.mobicents.media.server.spi.format.FormatFactory;
+import org.mobicents.media.server.spi.memory.Frame;
+import org.mobicents.media.server.spi.memory.Memory;
+import org.apache.log4j.Logger;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author yulian oifa
+ */
+public class DtmfInput extends AbstractSource {
+
+ private final static AudioFormat dtmf = FormatFactory.createAudioFormat("telephone-event", 8000);
+       private long period = 20000000L;
+    private int packetSize = 4;
+
+    private ArrayList<Frame> frameBuffer=new ArrayList(5);
+    private Frame currFrame;
+
+    private byte currTone=(byte)0xFF;
+    private long latestTime=0;
+    private int latestSeq=0;
+    private short eventDuration=0;
+    byte[] data = new byte[4];
+
+    private RtpClock clock;
+
+    private OOBInput input;
+
+ private static final Logger logger = Logger.getLogger(DtmfConverter.class);
+
+    public DtmfInput(Scheduler scheduler,RtpClock clock)
+    {
+       super("dtmfconverter", scheduler,scheduler.INPUT_QUEUE);
+       this.clock=clock;
+       input=new OOBInput(2);
+        this.connect(input);
+    }
+
+    public OOBInput getOOBInput()
+    {
+       return this.input;
+    }
+
+    public void setClock(RtpClock clock)
+    {
+        this.clock = clock;
+    }
+
+    public void write(RtpPacket event)
+    {
+       //obtain payload
+        event.getPyalod(data, 0);
+
+        if(data.length==0)
+               return;
+
+       boolean endOfEvent=false;
+        if(data.length>1)
+            endOfEvent=(data[1] & 0X80)!=0;
+
+       //lets ignore end of event packets
+        if(endOfEvent)
+               return;
+
+ //lets update sync data , allowing same tone come after 160ms from previous tone , not including end of tone
+        if(currTone==data[0])
+        {
+ if((event.getSeqNumber()<(latestSeq+8)) && event.getSeqNumber()>(latestSeq-8))
+               {
+                       if(event.getSeqNumber()>latestSeq)
+                       {
+                               latestSeq=event.getSeqNumber();
+                               latestTime=event.getTimestamp();
+                       }
+
+                return;
+               }
+
+ if(event.getTimestamp()<(latestTime+160) && event.getTimestamp()>(latestTime-160))
+               {
+                       if(event.getTimestamp()>latestTime)
+                       {
+                               latestSeq=event.getSeqNumber();
+                               latestTime=event.getTimestamp();
+                       }
+
+                return;
+            }
+        }
+
+        latestSeq=event.getSeqNumber();
+        latestTime=event.getTimestamp();
+        currTone=data[0];
+        for(int i=0;i<7;i++)
+        {
+               currFrame = Memory.allocate(packetSize);
+               byte[] newData=currFrame.getData();
+               newData[0]=data[0];
+               newData[1]=(byte)(0x3F & data[1]);
+               eventDuration=(short)(160*i);
+               newData[2]=(byte)((eventDuration>>8) & 0xFF);
+               newData[3]=(byte)(eventDuration & 0xFF);
+               currFrame.setSequenceNumber(event.getSeqNumber()+i);
+               currFrame.setOffset(0);
+            currFrame.setLength(packetSize);
+            currFrame.setFormat(dtmf);
+            currFrame.setDuration(period);
+ System.arraycopy(DtmfTonesData.buffer[data[0]], i*packetSize, currFrame.getData(), 0, packetSize); + currFrame.setTimestamp(clock.convertToAbsoluteTime(event.getTimestamp() + 20*i));
+            frameBuffer.add(currFrame);
+        }
+
+        for(int i=7;i<10;i++)
+        {
+               currFrame = Memory.allocate(packetSize);
+               byte[] newData=currFrame.getData();
+               newData[0]=data[0];
+               newData[1]=(byte)(0x80 | data[1]);
+               eventDuration=(short)(160*i);
+               newData[2]=(byte)((eventDuration>>8) & 0xFF);
+               newData[3]=(byte)(eventDuration & 0xFF);
+               currFrame.setSequenceNumber(event.getSeqNumber()+i);
+               currFrame.setOffset(0);
+            currFrame.setLength(packetSize);
+            currFrame.setFormat(dtmf);
+            currFrame.setDuration(period);
+ System.arraycopy(DtmfTonesData.buffer[data[0]], i*packetSize, currFrame.getData(), 0, packetSize); + currFrame.setTimestamp(clock.convertToAbsoluteTime(event.getTimestamp() + 20*i));
+            frameBuffer.add(currFrame);
+        }
+
+        wakeup();
+    }
+
+    @Override
+    public Frame evolve(long timestamp)
+    {
+       if (frameBuffer.size()==0)
+               return null;
+
+       return frameBuffer.remove(0);
+    }
+
+    public void reset()
+    {
+       latestSeq=0;
+               latestTime=0;
+               currTone=(byte)0xFF;
+    }
+}
=======================================
--- /dev/null
+++ /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/rfc2833/DtmfOutput.java Fri Jan 4 07:17:31 2013
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.mobicents.media.server.impl.rtp.rfc2833;
+
+import org.mobicents.media.server.impl.rtp.sdp.RTPFormats;
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.SelectionKey;
+import java.text.Format;
+import org.mobicents.media.server.component.oob.OOBOutput;
+import org.mobicents.media.MediaSink;
+import org.mobicents.media.MediaSource;
+import org.mobicents.media.server.impl.AbstractSink;
+import org.mobicents.media.server.impl.AbstractSource;
+import org.mobicents.media.server.impl.rtp.sdp.RTPFormat;
+import org.mobicents.media.server.impl.rtp.RTPDataChannel;
+import org.mobicents.media.server.io.network.ProtocolHandler;
+import org.mobicents.media.server.scheduler.Scheduler;
+import org.mobicents.media.server.scheduler.Task;
+import org.mobicents.media.server.spi.FormatNotSupportedException;
+import org.mobicents.media.server.spi.ConnectionMode;
+import org.mobicents.media.server.spi.format.AudioFormat;
+import org.mobicents.media.server.spi.format.FormatFactory;
+import org.mobicents.media.server.spi.format.Formats;
+import org.mobicents.media.server.spi.memory.Frame;
+import org.apache.log4j.Logger;
+/**
+ *
+ * @author Yulian oifa
+ */
+/**
+ * Transmitter implementation.
+ *
+ */
+public class DtmfOutput extends AbstractSink {
+ private final static AudioFormat dtmf = FormatFactory.createAudioFormat("telephone-event", 8000);
+
+    private RTPDataChannel channel;
+
+ private static final Logger logger = Logger.getLogger(DtmfOutput.class);
+
+    private OOBOutput oobOutput;
+
+    /**
+     * Creates new transmitter
+     */
+    public DtmfOutput(Scheduler scheduler,RTPDataChannel channel) {
+        super("Output");
+        this.channel=channel;
+        oobOutput=new OOBOutput(scheduler,1);
+        oobOutput.join(this);
+    }
+
+    public OOBOutput getOOBOutput()
+    {
+       return this.oobOutput;
+    }
+
+    public void activate()
+    {
+       oobOutput.start();
+    }
+
+    public void deactivate()
+    {
+       oobOutput.stop();
+    }
+
+    @Override
+    public void onMediaTransfer(Frame frame) throws IOException {
+       channel.sendDtmf(frame);
+    }
+}
=======================================
--- /client/jsr-309/tck/media/decreasingvolume-recorded.wav Tue Jan 1 16:15:51 2013 +++ /client/jsr-309/tck/media/decreasingvolume-recorded.wav Fri Jan 4 07:17:31 2013
Binary file, no diff available.
=======================================
--- /client/jsr-309/tck/server.log      Tue Jan  1 16:15:51 2013
+++ /client/jsr-309/tck/server.log      Fri Jan  4 07:17:31 2013
@@ -1,6 +1,6 @@
-2013-01-02 01:40:10,451 DEBUG [TestBase] (main) Loading file:/opt/mobsource/medianew/client/jsr-309/tck/exclude-list.properties -2013-01-02 01:40:10,452 INFO [Runner] (main) Start mandatory.functional.mediagroup.PlayerTest.test_2_1_1_1_Play javadoc::Joinable::1 javadoc::MediaGroup::1 javadoc::MediaGroup::6 javadoc::Player::1 javadoc::PlayerEvent::15 -2013-01-02 01:40:10,452 DEBUG [TestBase] (main) Getting a MsControlFactory instance -2013-01-02 01:40:10,474 INFO [DriverImpl] (main) Initializing MGCP on /127.0.0.1:2729 -2013-01-02 01:40:10,487 WARN [JainMgcpStackImpl] (main) Failed to locate properties file, using default values -2013-01-02 01:40:10,497 INFO [JainMgcpStackImpl] (main) Jain Mgcp stack bound to IP /127.0.0.1 and UDP port 2729 +2013-01-04 16:49:09,719 DEBUG [TestBase] (main) Loading file:/opt/mobsource/medianew/client/jsr-309/tck/exclude-list.properties +2013-01-04 16:49:09,730 INFO [Runner] (main) Start mandatory.functional.mediagroup.PlayerTest.test_2_1_1_1_Play javadoc::Joinable::1 javadoc::MediaGroup::1 javadoc::MediaGroup::6 javadoc::Player::1 javadoc::PlayerEvent::15 +2013-01-04 16:49:09,730 DEBUG [TestBase] (main) Getting a MsControlFactory instance +2013-01-04 16:49:09,752 INFO [DriverImpl] (main) Initializing MGCP on /127.0.0.1:2729 +2013-01-04 16:49:09,767 WARN [JainMgcpStackImpl] (main) Failed to locate properties file, using default values +2013-01-04 16:49:09,776 INFO [JainMgcpStackImpl] (main) Jain Mgcp stack bound to IP /127.0.0.1 and UDP port 2729
=======================================
--- /core/src/main/java/org/mobicents/media/core/connections/BaseConnection.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/connections/BaseConnection.java Fri Jan 4 07:17:31 2013
@@ -31,6 +31,7 @@
 import org.mobicents.media.server.utils.Text;

 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.server.impl.rtp.sdp.AVProfile;
 import org.mobicents.media.server.impl.rtp.sdp.RTPFormat;
 import org.mobicents.media.server.impl.rtp.sdp.RTPFormats;
@@ -102,6 +103,8 @@

     public abstract AudioComponent getAudioComponent();

+    public abstract OOBComponent getOOBComponent();
+
     /**
      * (Non Java-doc).
      *
=======================================
--- /core/src/main/java/org/mobicents/media/core/connections/LocalConnectionImpl.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/connections/LocalConnectionImpl.java Fri Jan 4 07:17:31 2013
@@ -30,6 +30,7 @@
 import org.mobicents.media.server.spi.ModeNotSupportedException;
 import org.mobicents.media.server.spi.ConnectionFailureListener;
 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.server.impl.rtp.ChannelsManager;
 import org.mobicents.media.server.impl.rtp.LocalDataChannel;
 import org.mobicents.media.server.utils.Text;
@@ -51,6 +52,11 @@
     {
        return this.localAudioChannel.getAudioComponent();
     }
+
+    public OOBComponent getOOBComponent()
+    {
+       return this.localAudioChannel.getOOBComponent();
+    }

     @Override
     public void setOtherParty(Connection other) throws IOException {
=======================================
--- /core/src/main/java/org/mobicents/media/core/connections/RtpConnectionImpl.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/connections/RtpConnectionImpl.java Fri Jan 4 07:17:31 2013
@@ -38,6 +38,7 @@
 import org.mobicents.media.server.spi.dsp.DspFactory;
 import org.mobicents.media.core.SdpTemplate;
 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.server.impl.rtp.ChannelsManager;
 import org.mobicents.media.server.impl.rtp.RTPDataChannel;
 import org.mobicents.media.server.impl.rtp.RTPChannelListener;
@@ -112,6 +113,11 @@
     {
        return this.rtpAudioChannel.getAudioComponent();
     }
+
+    public OOBComponent getOOBComponent()
+    {
+       return this.rtpAudioChannel.getOOBComponent();
+    }

     /**
* Gets whether connection should be bound to local or remote interface , supported only for rtp connections.
=======================================
--- /core/src/main/java/org/mobicents/media/core/endpoints/BaseMixerEndpointImpl.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/endpoints/BaseMixerEndpointImpl.java Fri Jan 4 07:17:31 2013
@@ -31,6 +31,7 @@
 import org.mobicents.media.MediaSource;
 import org.mobicents.media.core.connections.BaseConnection;
 import org.mobicents.media.server.component.audio.AudioMixer;
+import org.mobicents.media.server.component.oob.OOBMixer;
 import org.mobicents.media.server.scheduler.Clock;
 import org.mobicents.media.server.scheduler.Scheduler;
 import org.mobicents.media.server.spi.Connection;
@@ -52,6 +53,7 @@
 public class BaseMixerEndpointImpl extends BaseEndpointImpl {

        protected AudioMixer audioMixer;
+       protected OOBMixer oobMixer;

        private AtomicInteger loopbackCount=new AtomicInteger(0);
        private AtomicInteger readCount=new AtomicInteger(0);
@@ -70,6 +72,7 @@
        super.start();

        audioMixer=new AudioMixer(getScheduler());
+       oobMixer=new OOBMixer(getScheduler());
     }

     /**
@@ -80,6 +83,7 @@
public Connection createConnection(ConnectionType type,Boolean isLocal) throws ResourceUnavailableException {
        Connection connection=super.createConnection(type,isLocal);
audioMixer.addComponent(((BaseConnection)connection).getAudioComponent());
+       oobMixer.addComponent(((BaseConnection)connection).getOOBComponent());
         return connection;
     }

@@ -91,6 +95,7 @@
public void deleteConnection(Connection connection,ConnectionType connectionType) {
        super.deleteConnection(connection,connectionType);
        audioMixer.release(((BaseConnection)connection).getAudioComponent());
+       oobMixer.release(((BaseConnection)connection).getOOBComponent());
     }

     //should be handled on higher layers
@@ -141,9 +146,15 @@
                writeCount=this.writeCount.addAndGet(writeCount);

                if(loopbackCount>0 || readCount==0 || writeCount==0)
+               {
                        audioMixer.stop();
+                       oobMixer.stop();
+               }
                else
-                       audioMixer.start();
+               {
+                       audioMixer.start();
+                       oobMixer.start();
+               }
        }
     }
 }
=======================================
--- /core/src/main/java/org/mobicents/media/core/endpoints/BaseSS7EndpointImpl.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/endpoints/BaseSS7EndpointImpl.java Fri Jan 4 07:17:31 2013
@@ -31,6 +31,7 @@
 import org.mobicents.media.MediaSource;
 import org.mobicents.media.core.connections.BaseConnection;
 import org.mobicents.media.server.component.audio.AudioSplitter;
+import org.mobicents.media.server.component.oob.OOBSplitter;
 import org.mobicents.media.server.io.ss7.SS7DataChannel;
 import org.mobicents.media.server.impl.rtp.ChannelsManager;
 import org.mobicents.media.server.scheduler.Clock;
@@ -54,6 +55,7 @@
 public class BaseSS7EndpointImpl extends BaseEndpointImpl {

        protected AudioSplitter audioSplitter;
+       protected OOBSplitter oobSplitter;

        private AtomicInteger loopbackCount=new AtomicInteger(0);
        private AtomicInteger readCount=new AtomicInteger(0);
@@ -81,7 +83,9 @@
        super.start();

        audioSplitter=new AudioSplitter(getScheduler());
+       oobSplitter=new OOBSplitter(getScheduler());
        audioSplitter.addOutsideComponent(mediaGroup.getAudioComponent());
+       oobSplitter.addOutsideComponent(mediaGroup.getOOBComponent());

        try {
                ss7DataChannel=channelsManager.getSS7Channel(channelID,isALaw);
@@ -97,7 +101,9 @@
         catch(Exception e) {
//exception may happen only if invalid classes have been set in config
         }
+
        audioSplitter.addInsideComponent(ss7DataChannel.getAudioComponent());
+       oobSplitter.addInsideComponent(ss7DataChannel.getOOBComponent());
     }

     /**
@@ -107,7 +113,9 @@
      */
     public void stop() {
audioSplitter.releaseInsideComponent(ss7DataChannel.getAudioComponent());
+       oobSplitter.releaseInsideComponent(ss7DataChannel.getOOBComponent());
        audioSplitter.releaseOutsideComponent(mediaGroup.getAudioComponent());
+       oobSplitter.releaseOutsideComponent(mediaGroup.getOOBComponent());
        super.stop();
     }

@@ -119,6 +127,7 @@
public Connection createConnection(ConnectionType type,Boolean isLocal) throws ResourceUnavailableException {
        Connection connection=super.createConnection(type,isLocal);
audioSplitter.addOutsideComponent(((BaseConnection)connection).getAudioComponent()); + oobSplitter.addOutsideComponent(((BaseConnection)connection).getOOBComponent());

        if(getActiveConnectionsCount()==1)
        {
@@ -138,6 +147,7 @@
public void deleteConnection(Connection connection,ConnectionType connectionType) {
        super.deleteConnection(connection,connectionType);
audioSplitter.releaseOutsideComponent(((BaseConnection)connection).getAudioComponent()); + oobSplitter.releaseOutsideComponent(((BaseConnection)connection).getOOBComponent());

        if(getActiveConnectionsCount()==0)
        {
@@ -195,9 +205,15 @@
                writeCount=this.writeCount.addAndGet(writeCount);

                if(loopbackCount>0 || readCount==0 || writeCount==0)
+               {
                        audioSplitter.stop();
+                       oobSplitter.stop();
+               }
                else
+               {
                        audioSplitter.start();
+                       oobSplitter.start();
+               }
        }
     }

@@ -209,13 +225,17 @@
                ss7DataChannel.activateLoop();
                loopbackCount.addAndGet(1);
                audioSplitter.stop();
+               oobSplitter.stop();
        }
        else if(!toSet && oldState)
        {
                ss7DataChannel.deactivateLoop();
                loopbackCount.addAndGet(-1);
                if(loopbackCount.get()==0 && readCount.get()>0 && 
writeCount.get()>0)
+               {
                        audioSplitter.start();
+                       oobSplitter.start();
+               }
        }
     }
     public void configure(boolean isALaw)
=======================================
--- /core/src/main/java/org/mobicents/media/core/endpoints/BaseSplitterEndpointImpl.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/endpoints/BaseSplitterEndpointImpl.java Fri Jan 4 07:17:31 2013
@@ -31,6 +31,7 @@
 import org.mobicents.media.MediaSource;
 import org.mobicents.media.core.connections.BaseConnection;
 import org.mobicents.media.server.component.audio.AudioSplitter;
+import org.mobicents.media.server.component.oob.OOBSplitter;
 import org.mobicents.media.server.scheduler.Clock;
 import org.mobicents.media.server.scheduler.Scheduler;
 import org.mobicents.media.server.spi.Connection;
@@ -52,6 +53,7 @@
 public class BaseSplitterEndpointImpl extends BaseEndpointImpl {

        protected AudioSplitter audioSplitter;
+       protected OOBSplitter oobSplitter;

        private AtomicInteger loopbackCount=new AtomicInteger(0);
        private AtomicInteger readCount=new AtomicInteger(0);
@@ -70,6 +72,7 @@
        super.start();

        audioSplitter=new AudioSplitter(getScheduler());
+       oobSplitter=new OOBSplitter(getScheduler());
     }

     /**
@@ -84,9 +87,11 @@
        {
                case RTP:
audioSplitter.addOutsideComponent(((BaseConnection)connection).getAudioComponent()); + oobSplitter.addOutsideComponent(((BaseConnection)connection).getOOBComponent());
                        break;
                case LOCAL:
audioSplitter.addInsideComponent(((BaseConnection)connection).getAudioComponent()); + oobSplitter.addInsideComponent(((BaseConnection)connection).getOOBComponent());
                break;
        }

@@ -105,9 +110,11 @@
        {
                case RTP:
audioSplitter.releaseOutsideComponent(((BaseConnection)connection).getAudioComponent()); + oobSplitter.releaseOutsideComponent(((BaseConnection)connection).getOOBComponent());
                        break;
                case LOCAL:
audioSplitter.releaseInsideComponent(((BaseConnection)connection).getAudioComponent()); + oobSplitter.releaseInsideComponent(((BaseConnection)connection).getOOBComponent());
                break;
        }
     }
@@ -160,9 +167,15 @@
                writeCount=this.writeCount.addAndGet(writeCount);

                if(loopbackCount>0 || readCount==0 || writeCount==0)
+               {
                        audioSplitter.stop();
+                       oobSplitter.stop();
+               }
                else
+               {
                        audioSplitter.start();
+                       oobSplitter.start();
+               }
        }
     }
 }
=======================================
--- /core/src/main/java/org/mobicents/media/core/endpoints/MediaGroup.java Tue Jan 1 16:15:51 2013 +++ /core/src/main/java/org/mobicents/media/core/endpoints/MediaGroup.java Fri Jan 4 07:17:31 2013
@@ -28,6 +28,7 @@
 import org.mobicents.media.server.spi.ConnectionMode;
 import org.mobicents.media.server.spi.Endpoint;
 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.core.ResourcesPool;

 import org.mobicents.media.server.impl.resource.dtmf.DetectorImpl;
@@ -55,15 +56,18 @@
        private ResourcesPool resourcesPool;

        private AudioComponent audioComponent;
+       private OOBComponent oobComponent;

        private Endpoint endpoint;

        private int readComponents=0,writeComponents=0;
+       private int readDtmfComponents=0,writeDtmfComponents=0;

        public MediaGroup(ResourcesPool resourcesPool,Endpoint endpoint)
        {
                this.resourcesPool=resourcesPool;
                this.audioComponent=new AudioComponent(0);
+               this.oobComponent=new OOBComponent(0);
                this.endpoint=endpoint;
        }

@@ -71,6 +75,11 @@
        {
                return this.audioComponent;
        }
+
+       public OOBComponent getOOBComponent()
+       {
+               return this.oobComponent;
+       }

        public Component getPlayer()
        {
@@ -114,8 +123,11 @@
                        
this.recorder=resourcesPool.newAudioComponent(ComponentType.RECORDER);
                        this.recorder.setEndpoint(endpoint);
audioComponent.addOutput(((AudioRecorderImpl)this.recorder).getAudioOutput()); + oobComponent.addOutput(((AudioRecorderImpl)this.recorder).getOOBOutput());
                        writeComponents++;
+                       writeDtmfComponents++;
                        audioComponent.updateMode(readComponents!=0,true);
+                       oobComponent.updateMode(readDtmfComponents!=0,true);
                        updateEndpoint(0,1);
                }

@@ -127,8 +139,11 @@
                if(this.recorder!=null)
                {
audioComponent.remove(((AudioRecorderImpl)this.recorder).getAudioOutput());
+                       
oobComponent.remove(((AudioRecorderImpl)this.recorder).getOOBOutput());
                        writeComponents--;
+                       writeDtmfComponents--;
                        
audioComponent.updateMode(readComponents!=0,writeComponents!=0);
+                       
oobComponent.updateMode(readDtmfComponents!=0,writeDtmfComponents!=0);
                        updateEndpoint(0,-1);
                        this.recorder.clearEndpoint();
                        ((AudioRecorderImpl)this.recorder).clearAllListeners();
@@ -150,8 +165,11 @@
this.dtmfDetector=resourcesPool.newAudioComponent(ComponentType.DTMF_DETECTOR);
                        this.dtmfDetector.setEndpoint(endpoint);
audioComponent.addOutput(((DetectorImpl)this.dtmfDetector).getAudioOutput()); + oobComponent.addOutput(((DetectorImpl)this.dtmfDetector).getOOBOutput());
                        writeComponents++;
+                       writeDtmfComponents++;
                        audioComponent.updateMode(readComponents!=0,true);
+                       oobComponent.updateMode(readDtmfComponents!=0,true);
                        updateEndpoint(0,1);
                }

@@ -163,8 +181,11 @@
                if(this.dtmfDetector!=null)
                {
audioComponent.remove(((DetectorImpl)this.dtmfDetector).getAudioOutput());
+                       
oobComponent.remove(((DetectorImpl)this.dtmfDetector).getOOBOutput());
                        writeComponents--;
+                       writeDtmfComponents--;
                        
audioComponent.updateMode(readComponents!=0,writeComponents!=0);
+                       
oobComponent.updateMode(readDtmfComponents!=0,writeDtmfComponents!=0);
                        updateEndpoint(0,-1);
                        this.dtmfDetector.clearEndpoint();
                        ((DetectorImpl)this.dtmfDetector).clearAllListeners();
@@ -187,8 +208,10 @@
this.dtmfGenerator=resourcesPool.newAudioComponent(ComponentType.DTMF_GENERATOR);
                        this.dtmfGenerator.setEndpoint(endpoint);
audioComponent.addInput(((GeneratorImpl)this.dtmfGenerator).getAudioInput()); + oobComponent.addInput(((GeneratorImpl)this.dtmfGenerator).getOOBInput());
                        readComponents++;
-                       audioComponent.updateMode(true,writeComponents!=0);
+                       readDtmfComponents++;
+                       audioComponent.updateMode(true,writeDtmfComponents!=0);
                        updateEndpoint(1,0);
                }

@@ -200,8 +223,10 @@
                if(this.dtmfGenerator!=null)
                {
audioComponent.remove(((GeneratorImpl)this.dtmfGenerator).getAudioInput());
+                       
oobComponent.remove(((GeneratorImpl)this.dtmfGenerator).getOOBInput());
                        readComponents--;
-                       
audioComponent.updateMode(readComponents!=0,writeComponents!=0);
+                       readDtmfComponents--;
+                       
oobComponent.updateMode(readDtmfComponents!=0,writeDtmfComponents!=0);
                        updateEndpoint(-1,0);
                        this.dtmfGenerator.clearEndpoint();
                        this.dtmfGenerator.deactivate();
=======================================
--- /core/src/test/java/org/mobicents/media/core/connections/MyTestConnection.java Tue Jan 1 16:15:51 2013 +++ /core/src/test/java/org/mobicents/media/core/connections/MyTestConnection.java Fri Jan 4 07:17:31 2013
@@ -29,6 +29,7 @@
 import java.io.IOException;
 import org.mobicents.media.server.scheduler.Scheduler;
 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.server.spi.Connection;
 import org.mobicents.media.server.spi.MediaType;
 import org.mobicents.media.server.utils.Text;
@@ -46,15 +47,22 @@
     private volatile boolean failed;

     private AudioComponent audioComponent;
+    private OOBComponent oobComponent;
public MyTestConnection(String id,Scheduler scheduler) throws Exception {
         super(id, scheduler);
         audioComponent=new AudioComponent(-1);
+        oobComponent=new OOBComponent(-1);
     }

     public AudioComponent getAudioComponent()
     {
        return audioComponent;
     }
+
+    public OOBComponent getOOBComponent()
+    {
+       return oobComponent;
+    }

     public void setOtherParty(Connection other) throws IOException {
         throw new UnsupportedOperationException("Not supported yet.");
=======================================
--- /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/LocalDataChannel.java Tue Jan 1 16:15:51 2013 +++ /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/LocalDataChannel.java Fri Jan 4 07:17:31 2013
@@ -27,6 +27,9 @@
 import org.mobicents.media.server.component.audio.AudioInput;
 import org.mobicents.media.server.component.audio.AudioOutput;
 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBInput;
+import org.mobicents.media.server.component.oob.OOBOutput;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.server.scheduler.Scheduler;
 import org.mobicents.media.server.spi.ConnectionMode;
 import org.mobicents.media.server.spi.format.FormatFactory;
@@ -49,6 +52,10 @@
        private AudioInput input;
        private AudioOutput output;

+       private OOBComponent oobComponent;
+       private OOBInput oobInput;
+       private OOBOutput oobOutput;
+
        private LocalDataChannel otherChannel=null;

        /**
@@ -60,6 +67,12 @@
        output=new AudioOutput(channelsManager.getScheduler(),2);
        audioComponent.addInput(input);
        audioComponent.addOutput(output);
+
+       oobComponent=new OOBComponent(channelId);
+       oobInput=new OOBInput(1);
+       oobOutput=new OOBOutput(channelsManager.getScheduler(),2);
+       oobComponent.addInput(oobInput);
+       oobComponent.addOutput(oobOutput);
     }

     public AudioInput getAudioInput()
@@ -76,6 +89,21 @@
     {
        return this.audioComponent;
     }
+
+    public OOBInput getOOBInput()
+    {
+       return this.oobInput;
+    }
+
+    public OOBOutput getOOBOutput()
+    {
+       return this.oobOutput;
+    }
+
+    public OOBComponent getOOBComponent()
+    {
+       return this.oobComponent;
+    }

     public void join(LocalDataChannel otherChannel) throws IOException
     {
@@ -85,7 +113,9 @@
        this.otherChannel=otherChannel;
        otherChannel.otherChannel=this;
        this.otherChannel.getAudioOutput().join(input);
+       this.otherChannel.getOOBOutput().join(oobInput);
        output.join(this.otherChannel.getAudioInput());
+       oobOutput.join(this.otherChannel.getOOBInput());
     }

     public void unjoin()
@@ -94,7 +124,10 @@
                return;

        this.output.deactivate();
-       output.unjoin();
+       this.oobOutput.deactivate();
+       output.unjoin();
+       oobOutput.unjoin();
+
        this.otherChannel=null;
     }

@@ -106,23 +139,31 @@
        switch (connectionMode) {
                case SEND_ONLY:
                        audioComponent.updateMode(false,true);
-                       output.activate();
+                       oobComponent.updateMode(false,true);
+                       output.activate();
+                       oobOutput.activate();
                        break;
                case RECV_ONLY:
                        audioComponent.updateMode(true,false);
-                       output.deactivate();
+                       oobComponent.updateMode(true,false);
+                       output.deactivate();
+                       oobOutput.deactivate();
                        break;
                case INACTIVE:
                        audioComponent.updateMode(false,false);
-                       output.deactivate();
+                       oobComponent.updateMode(false,false);
+                       output.deactivate();
+                       oobOutput.deactivate();
                        break;
                case SEND_RECV:
                case CONFERENCE:
                        audioComponent.updateMode(true,true);
-                       output.activate();
+                       oobComponent.updateMode(true,true);
+                       output.activate();
+                       oobOutput.activate();
                        break;
                case NETWORK_LOOPBACK:
throw new ModeNotSupportedException("Loopback not supported on local channel");
-       }
+       }
     }
 }
=======================================
--- /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/RTPDataChannel.java Tue Jan 1 16:15:51 2013 +++ /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/RTPDataChannel.java Fri Jan 4 07:17:31 2013
@@ -23,6 +23,7 @@
 package org.mobicents.media.server.impl.rtp;

 import org.mobicents.media.server.impl.rtp.sdp.RTPFormats;
+import org.mobicents.media.server.impl.rtp.sdp.AVProfile;
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.net.InetSocketAddress;
@@ -34,7 +35,9 @@
 import org.mobicents.media.MediaSink;
 import org.mobicents.media.MediaSource;
 import org.mobicents.media.server.component.audio.AudioComponent;
-import org.mobicents.media.server.impl.rtp.rfc2833.DtmfConverter;
+import org.mobicents.media.server.component.oob.OOBComponent;
+import org.mobicents.media.server.impl.rtp.rfc2833.DtmfInput;
+import org.mobicents.media.server.impl.rtp.rfc2833.DtmfOutput;
 import org.mobicents.media.server.impl.AbstractSink;
 import org.mobicents.media.server.impl.AbstractSource;
 import org.mobicents.media.server.impl.rtp.sdp.RTPFormat;
@@ -78,8 +81,9 @@
     //Receiver and transmitter
     private RTPInput input;
     private RTPOutput output;
-    //RTP dtmf event converter
-    private DtmfConverter dtmfConverter;
+    //RTP dtmf receiver and trasmitter
+    private DtmfInput dtmfInput;
+    private DtmfOutput dtmfOutput;

     //tx task - sender
     private TxTask tx = new TxTask();
@@ -121,6 +125,10 @@
     private Logger logger = Logger.getLogger(RTPDataChannel.class) ;

     private AudioComponent audioComponent;
+    private OOBComponent oobComponent;
+
+    private boolean sendDtmf=false;
+
     /**
      * Create RTP channel instance.
      *
@@ -148,22 +156,31 @@
         //transmittor
         output = new RTPOutput(scheduler,this);

-        dtmfConverter=new DtmfConverter(scheduler,rtpClock);
+        dtmfInput=new DtmfInput(scheduler,rtpClock);
+        dtmfOutput=new DtmfOutput(scheduler,this);

         heartBeat=new HeartBeat();

         formats.add(format);

         audioComponent=new AudioComponent(channelId);
-        audioComponent.addInput(dtmfConverter.getAudioInput());
         audioComponent.addInput(input.getAudioInput());
         audioComponent.addOutput(output.getAudioOutput());
+
+        oobComponent=new OOBComponent(channelId);
+        oobComponent.addInput(dtmfInput.getOOBInput());
+        oobComponent.addOutput(dtmfOutput.getOOBOutput());
     }

     public AudioComponent getAudioComponent()
     {
        return this.audioComponent;
     }
+
+    public OOBComponent getOOBComponent()
+    {
+       return this.oobComponent;
+    }

     public void setInputDsp(Processor dsp) {
        input.setDsp(dsp);
@@ -196,42 +213,52 @@
                        shouldReceive=false;
                        shouldLoop=false;
                        audioComponent.updateMode(false,true);
-                       dtmfConverter.deactivate();
+                       oobComponent.updateMode(false,true);
+                       dtmfInput.deactivate();
                        input.deactivate();
                        output.activate();
+                       dtmfOutput.activate();
                        break;
                case RECV_ONLY:
                        shouldReceive=true;
                        shouldLoop=false;
                        audioComponent.updateMode(true,false);
-                       dtmfConverter.activate();
+                       oobComponent.updateMode(true,false);
+                       dtmfInput.activate();
                        input.activate();
                        output.deactivate();
+                       dtmfOutput.deactivate();
                        break;
                case INACTIVE:
                        shouldReceive=false;
                        shouldLoop=false;
                        audioComponent.updateMode(false,false);
-                       dtmfConverter.deactivate();
+                       oobComponent.updateMode(false,false);
+                       dtmfInput.deactivate();
                        input.deactivate();
                        output.deactivate();
+                       dtmfOutput.deactivate();
                        break;
                case SEND_RECV:
                case CONFERENCE:
                        shouldReceive=true;
                        shouldLoop=false;
                        audioComponent.updateMode(true,true);
-                       dtmfConverter.activate();
+                       oobComponent.updateMode(true,true);
+                       dtmfInput.activate();
                        input.activate();
                        output.activate();
+                       dtmfOutput.activate();
                        break;
                case NETWORK_LOOPBACK:
                        shouldReceive=false;
                        shouldLoop=true;
                        audioComponent.updateMode(false,false);
-                       dtmfConverter.deactivate();
+                       oobComponent.updateMode(false,false);
+                       dtmfInput.deactivate();
                        input.deactivate();
                        output.deactivate();
+                       dtmfOutput.deactivate();
                        break;
        }

@@ -359,12 +386,14 @@
         rxCount=0;
         txCount=0;
         input.deactivate();
-        dtmfConverter.deactivate();
-        dtmfConverter.reset();
-        output.deactivate();
+        dtmfInput.deactivate();
+        dtmfInput.reset();
+        output.deactivate();
+        dtmfOutput.deactivate();
         this.tx.clear();

-        heartBeat.cancel();
+        heartBeat.cancel();
+        sendDtmf=false;
     }

     public int getPacketsLost() {
@@ -385,6 +414,11 @@
      * @param rtpFormats the format map
      */
     public void setFormatMap(RTPFormats rtpFormats) {
+       if(rtpFormats.find(AVProfile.telephoneEventsID)!=null)
+               sendDtmf=true;
+       else
+               sendDtmf=false;
+
        this.rtpHandler.flush();
        this.rtpFormats = rtpFormats;
         this.rxBuffer.setFormats(rtpFormats);
@@ -395,6 +429,12 @@
        if(dataChannel.isConnected())
                tx.perform(frame);
     }
+
+    public void sendDtmf(Frame frame)
+    {
+       if(dataChannel.isConnected())
+               tx.performDtmf(frame);
+    }

     /**
      * Implements IO operations for RTP protocol.
@@ -577,7 +617,7 @@
                                else if(!shouldLoop) {
format = rtpFormats.find(rtpPacket.getPayloadType()); if (format != null && format.getFormat().matches(dtmf))
-                                               dtmfConverter.write(rtpPacket);
+                                               dtmfInput.write(rtpPacket);
                                        else
                                                
rxBuffer.write(rtpPacket,format);

@@ -617,6 +657,7 @@
        private RtpPacket rtpPacket = new RtpPacket(8192, true);
         private RTPFormat fmt;
         private long timestamp=-1;
+        private long dtmfTimestamp=-1;

         private TxTask() {
         }
@@ -627,12 +668,58 @@
          */
         public void clear() {
                this.timestamp=-1;
+               this.dtmfTimestamp=-1;
                this.fmt=null;
         }
+
+        public void performDtmf(Frame frame) {
+               if(!sendDtmf)
+               {
+                       frame.recycle();
+                       return;
+               }
+
+               //ignore frames with duplicate timestamp
+            if (frame.getTimestamp()/1000000L == dtmfTimestamp) {
+               frame.recycle();
+               return;
+            }
+
+               //convert to milliseconds first
+               dtmfTimestamp = frame.getTimestamp() / 1000000L;
+
+            //convert to rtp time units
+               dtmfTimestamp = rtpClock.convertToRtpTime(dtmfTimestamp);
+ rtpPacket.wrap(false, AVProfile.telephoneEventsID, sn++, dtmfTimestamp, + ssrc, frame.getData(), frame.getOffset(), frame.getLength());
+
+            frame.recycle();
+            try {
+                if (dataChannel.isConnected()) {
+ dataChannel.send(rtpPacket.getBuffer(),dataChannel.socket().getRemoteSocketAddress());
+                       txCount++;
+                }
+            }
+            catch(PortUnreachableException e) {
+               //icmp unreachable received
+               //disconnect and wait for new packet
+               try
+               {
+                       dataChannel.disconnect();
+               }
+               catch(IOException ex) {
+                       logger.error(ex);
+               }
+            }
+            catch (Exception e) {
+               logger.error(e);
+            }
+        }

         public void perform(Frame frame) {
             //discard frame if format is unknown
             if (frame.getFormat() == null) {
+               frame.recycle();
                return;
             }

@@ -641,6 +728,7 @@
                 fmt = rtpFormats.getRTPFormat(frame.getFormat());
                 //format still unknown? discard packet
                 if (fmt == null) {
+                       frame.recycle();
                        return;
                 }
                 //update clock rate
@@ -649,6 +737,7 @@

             //ignore frames with duplicate timestamp
             if (frame.getTimestamp()/1000000L == timestamp) {
+               frame.recycle();
                return;
             }

=======================================
--- /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/sdp/AVProfile.java Mon May 28 08:12:44 2012 +++ /io/rtp/src/main/java/org/mobicents/media/server/impl/rtp/sdp/AVProfile.java Fri Jan 4 07:17:31 2013
@@ -31,7 +31,7 @@
  * @author kulikov
  */
 public class AVProfile {
-
+       public final static int telephoneEventsID=101;
public final static AudioFormat telephoneEvent = FormatFactory.createAudioFormat("telephone-event", 8000);
     static {
         telephoneEvent.setOptions(new Text("0-15"));
@@ -44,7 +44,7 @@
private final static RTPFormat gsm = new RTPFormat(3, FormatFactory.createAudioFormat("gsm", 8000), 8000); private final static RTPFormat g729 = new RTPFormat(18, FormatFactory.createAudioFormat("g729", 8000), 8000); private final static RTPFormat l16 = new RTPFormat(97, FormatFactory.createAudioFormat("l16", 8000, 16, 1), 8000); - private final static RTPFormat dtmf = new RTPFormat(101, telephoneEvent, 8000); + private final static RTPFormat dtmf = new RTPFormat(telephoneEventsID, telephoneEvent, 8000); private final static RTPFormat ilbc = new RTPFormat(102, FormatFactory.createAudioFormat("ilbc", 8000, 16, 1), 8000); private final static RTPFormat linear = new RTPFormat(150, FormatFactory.createAudioFormat("linear", 8000, 16, 1), 8000);

=======================================
--- /io/ss7/src/main/java/org/mobicents/media/server/io/ss7/SS7DataChannel.java Tue Jan 1 16:15:51 2013 +++ /io/ss7/src/main/java/org/mobicents/media/server/io/ss7/SS7DataChannel.java Fri Jan 4 07:17:31 2013
@@ -28,6 +28,7 @@
 import java.net.SocketException;
 import java.text.Format;
 import org.mobicents.media.server.component.audio.AudioComponent;
+import org.mobicents.media.server.component.oob.OOBComponent;
 import org.mobicents.media.MediaSink;
 import org.mobicents.media.MediaSource;
 import org.mobicents.media.hardware.dahdi.SelectorKeyImpl;
@@ -80,6 +81,7 @@
     private boolean shouldLoop=false;

     private AudioComponent audioComponent;
+    private OOBComponent oobComponent;

     /**
      * Create SS7 channel instance.
@@ -112,12 +114,19 @@
        audioComponent=new AudioComponent(audioChannelID);
         audioComponent.addInput(input.getAudioInput());
         audioComponent.addOutput(output.getAudioOutput());
+
+        oobComponent=new OOBComponent(audioChannelID);
     }

     public AudioComponent getAudioComponent()
     {
        return this.audioComponent;
     }
+
+    public OOBComponent getOOBComponent()
+    {
+       return this.oobComponent;
+    }

     public void setOutputDsp(Processor dsp) {
        output.setDsp(dsp);
@@ -155,6 +164,7 @@
         input.activate();
        output.activate();
        audioComponent.updateMode(true,true);
+       oobComponent.updateMode(true,true);
     }

     /**
@@ -170,6 +180,7 @@
        input.deactivate();
         output.deactivate();
         audioComponent.updateMode(false,false);
+        oobComponent.updateMode(false,false);
         shouldLoop=true;
     }

@@ -177,6 +188,7 @@
        input.activate();
         output.activate();
         audioComponent.updateMode(true,true);
+        oobComponent.updateMode(true,true);
         shouldLoop=false;
     }

@@ -195,7 +207,8 @@
         txCount=0;
         input.deactivate();
         output.deactivate();
-        audioComponent.updateMode(false,false);
+        audioComponent.updateMode(false,false);
+        oobComponent.updateMode(false,false);
     }

     public int getPacketsLost() {
=======================================
--- /media-server-docs/sources-mobicents/src/main/resources/META-INF/MANIFEST.MF Tue Jan 1 16:15:51 2013 +++ /media-server-docs/sources-mobicents/src/main/resources/META-INF/MANIFEST.MF Fri Jan 4 07:17:31 2013
@@ -13,7 +13,7 @@
 Bundle-Vendor: TeleStax, Inc.
 Implementation-Vendor-Id: TeleStax, Inc.
 Bundle-Version: 3.0.0.FINAL-SNAPSHOT
-Bnd-LastModified: 1357083334110
+Bnd-LastModified: 1357310815220
 Bundle-ManifestVersion: 2
 Bundle-License: http://www.gnu.org/licenses/lgpl-2.1.html
 Bundle-Description: Mobicents :: Parent pom for 2.x releases
=======================================
--- /media-server-docs/sources-mobicents/src/main/resources/META-INF/maven/org.mobicents.media.docs/mobicents-mms-docs-sources/pom.properties Tue Jan 1 16:15:51 2013 +++ /media-server-docs/sources-mobicents/src/main/resources/META-INF/maven/org.mobicents.media.docs/mobicents-mms-docs-sources/pom.properties Fri Jan 4 07:17:31 2013
@@ -1,5 +1,5 @@
 #Generated by Maven
-#Wed Jan 02 01:35:34 IST 2013
+#Fri Jan 04 16:46:55 IST 2013
 version=3.0.0.FINAL-SNAPSHOT
 groupId=org.mobicents.media.docs
 artifactId=mobicents-mms-docs-sources
=======================================
--- /resources/recorder/src/main/java/org/mobicents/media/server/impl/resource/audio/AudioRecorderImpl.java Tue Jan 1 16:15:51 2013 +++ /resources/recorder/src/main/java/org/mobicents/media/server/impl/resource/audio/AudioRecorderImpl.java Fri Jan 4 07:17:31 2013
@@ -33,6 +33,7 @@

 import org.mobicents.media.ComponentType;
 import org.mobicents.media.server.component.audio.AudioOutput;
+import org.mobicents.media.server.component.oob.OOBOutput;
 import org.mobicents.media.server.impl.AbstractSink;
 import org.mobicents.media.server.scheduler.Scheduler;
 import org.mobicents.media.server.scheduler.Task;
@@ -109,6 +110,7 @@
     private boolean speechDetected=false;

     private AudioOutput output;
+    private OOBOutput oobOutput;

private static final Logger logger = Logger.getLogger(AudioRecorderImpl.class);

@@ -129,6 +131,7 @@
         heartbeat = new Heartbeat();

         output=new AudioOutput(scheduler,ComponentType.RECORDER.getType());
+ oobOutput=new OOBOutput(scheduler,ComponentType.RECORDER.getType());
         output.join(this);
     }

@@ -136,6 +139,11 @@
     {
        return this.output;
     }
+
+    public OOBOutput getOOBOutput()
+    {
+       return this.oobOutput;
+    }

     @Override
     public void activate() {
@@ -143,7 +151,7 @@
        this.startTime=scheduler.getClock().getTime();

        output.start();
-
+       oobOutput.start();
if(this.postSpeechTimer>0 || this.preSpeechTimer>0 || this.maxRecordTime>0)
                scheduler.submitHeatbeat(this.heartbeat);

@@ -158,6 +166,7 @@
         }

         output.stop();
+        oobOutput.stop();
         this.maxRecordTime = -1;
         this.lastPacketData=0;
         this.startTime=0;
=======================================
--- /resources/telephony/dtmf/src/main/java/org/mobicents/media/server/impl/resource/dtmf/DetectorImpl.java Tue Jan 1 16:15:51 2013 +++ /resources/telephony/dtmf/src/main/java/org/mobicents/media/server/impl/resource/dtmf/DetectorImpl.java Fri Jan 4 07:17:31 2013
@@ -29,6 +29,7 @@

 import org.mobicents.media.ComponentType;
 import org.mobicents.media.server.component.audio.AudioOutput;
+import org.mobicents.media.server.component.oob.OOBOutput;
 import org.mobicents.media.server.impl.AbstractSink;
 import org.mobicents.media.server.component.audio.GoertzelFilter;
 import org.mobicents.media.server.scheduler.Scheduler;
@@ -110,6 +111,7 @@
     private Scheduler scheduler;

     private AudioOutput output;
+    private OOBOutput oobOutput;

private static final Logger logger = Logger.getLogger(DetectorImpl.class) ;

@@ -132,6 +134,7 @@
         this.level = DEFAULT_SIGNAL_LEVEL;

         output=new AudioOutput(scheduler,ComponentType.RECORDER.getType());
+ oobOutput=new OOBOutput(scheduler,ComponentType.RECORDER.getType());
         output.join(this);
     }

@@ -139,6 +142,11 @@
     {
        return this.output;
     }
+
+    public OOBOutput getOOBOutput()
+    {
+       return this.oobOutput;
+    }

     public void activate()
     {
@@ -147,11 +155,13 @@

         this.dtmfBuffer.clear();
         output.start();
+        oobOutput.start();
     }

     public void deactivate()
     {
-       output.stop();
+       output.stop();
+       oobOutput.stop();
     }

     public void setDuration(int duartion) {
=======================================
--- /resources/telephony/dtmf/src/main/java/org/mobicents/media/server/impl/resource/dtmf/GeneratorImpl.java Tue Jan 1 16:15:51 2013 +++ /resources/telephony/dtmf/src/main/java/org/mobicents/media/server/impl/resource/dtmf/GeneratorImpl.java Fri Jan 4 07:17:31 2013
@@ -24,6 +24,7 @@

 import org.mobicents.media.ComponentType;
 import org.mobicents.media.server.component.audio.AudioInput;
+import org.mobicents.media.server.component.oob.OOBInput;
 import org.mobicents.media.server.impl.AbstractSource;
 import org.mobicents.media.server.scheduler.Scheduler;
 import org.mobicents.media.server.spi.format.AudioFormat;
@@ -77,12 +78,14 @@
     private double time = 0;

     private AudioInput input;
+    private OOBInput oobInput;

     public GeneratorImpl(String name, Scheduler scheduler) {
         super(name, scheduler,scheduler.INPUT_QUEUE);
         dt = 1.0 / linear.getSampleRate();

this.input=new AudioInput(ComponentType.DTMF_GENERATOR.getType(),packetSize);
+        this.oobInput=new OOBInput(ComponentType.DTMF_GENERATOR.getType());
         this.connect(this.input);
     }

@@ -90,6 +93,11 @@
     {
        return this.input;
     }
+
+    public OOBInput getOOBInput()
+    {
+       return this.oobInput;
+    }

     @Override
     public void activate() {

Reply via email to