diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java index 516c75f48..b8b0a85c4 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java @@ -514,6 +514,10 @@ public class JingleManager implements JingleSessionListener { jingleSessions.remove(jingleSession); } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + /** * Register the listenerJingles, waiting for a Jingle packet that tries to * establish a new session. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java index 557013629..3ba9dbbae 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java @@ -83,7 +83,7 @@ import java.util.*; * @see IncomingJingleSession * @see OutgoingJingleSession */ -public abstract class JingleSession extends JingleNegotiator { +public abstract class JingleSession extends JingleNegotiator implements MediaReceivedListener { // static private static final HashMap sessions = new HashMap(); @@ -432,7 +432,7 @@ public abstract class JingleSession extends JingleNegotiator { jout = getState().eventInitiate(jin); - + } else if (action.equals(Jingle.Action.SESSIONREDIRECT)) { jout = getState().eventRedirect(jin); @@ -1084,6 +1084,7 @@ public abstract class JingleSession extends JingleNegotiator { lc.removeCandidateEcho(); jingleMediaSession = jingleMediaManager.createMediaSession(pt, rc, lc); + jingleMediaSession.addMediaReceivedListener(this); if (jingleMediaSession != null) { jingleMediaSession.startTrasmit(); @@ -1097,6 +1098,21 @@ public abstract class JingleSession extends JingleNegotiator { } + /** + * Trigger a session closed event due to an error. + */ + protected void triggerMediaReceived(String participant) { + ArrayList listeners = getListenersList(); + Iterator iter = listeners.iterator(); + while (iter.hasNext()) { + JingleListener li = (JingleListener) iter.next(); + if (li instanceof JingleSessionListener) { + JingleSessionListener sli = (JingleSessionListener) li; + sli.sessionMediaReceived(this, participant); + } + } + } + /** * Trigger a session redirect event. */ @@ -1216,4 +1232,11 @@ public abstract class JingleSession extends JingleNegotiator { return iqError; } + + /** + * Called when new Media is received. + */ + public void mediaReceived(String participant) { + triggerMediaReceived(participant); + } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java index de8b7ac62..97d2c7eda 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java @@ -73,4 +73,13 @@ public interface JingleSessionListener extends JingleListener { * @param jingleSession session that called the method */ public void sessionClosedOnError(XMPPException e, JingleSession jingleSession); + + /** + * Notification that the Media has arrived for this session. + * + * @param jingleSession session that called the method + * @param participant description of the participant + */ + public void sessionMediaReceived(JingleSession jingleSession, String participant); + } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java index a905f3403..c9e73690a 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java @@ -21,6 +21,9 @@ package org.jivesoftware.smackx.jingle.media; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; +import java.util.List; +import java.util.ArrayList; + /** * Public Abstract Class provides a clear interface between Media Session and Jingle API. *

@@ -43,6 +46,8 @@ public abstract class JingleMediaSession { private TransportCandidate remote; // Media Locator private String mediaLocator; + // Media Received Listener + private List mediaReceivedListeners = new ArrayList(); /** * Creates a new JingleMediaSession Instance to handle Media methods. @@ -105,6 +110,31 @@ public abstract class JingleMediaSession { this.mediaLocator = mediaLocator; } + /** + * Adds a Media Received Listener + * + * @param mediaReceivedListener + */ + public void addMediaReceivedListener(MediaReceivedListener mediaReceivedListener) { + mediaReceivedListeners.add(mediaReceivedListener); + } + + /** + * Removes a Media Received Listener + * + * @param mediaReceivedListener + */ + public void removeMediaReceivedListener(MediaReceivedListener mediaReceivedListener) { + mediaReceivedListeners.remove(mediaReceivedListener); + } + + /** + * Removes all Media Received Listeners + */ + public void removeAllMediaReceivedListener() { + mediaReceivedListeners.clear(); + } + /** * Initialize the RTP Channel preparing to transmit and receive. */ @@ -138,4 +168,13 @@ public abstract class JingleMediaSession { */ public abstract void stopReceive(); + /** + * Called when new Media is received. + */ + public void mediaReceived(String participant) { + for (MediaReceivedListener mediaReceivedListener : mediaReceivedListeners) { + mediaReceivedListener.mediaReceived(participant); + } + } + } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java new file mode 100644 index 000000000..9268f63d3 --- /dev/null +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java @@ -0,0 +1,32 @@ +/** + * $RCSfile$ + * $Revision: $ + * $Date: $11-07-2006 + * + * Copyright 2003-2006 Jive Software. + * + * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.jingle.media; + +/** + * Listener for new Incoming Media Streams + */ +public interface MediaReceivedListener { + + /** + * Called when new Media is received. + */ + public void mediaReceived(String participant); + +} diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java index b1b648dcc..633baef2d 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java @@ -19,6 +19,8 @@ */ package org.jivesoftware.smackx.jingle.mediaimpl.jmf; +import org.jivesoftware.smackx.jingle.media.JingleMediaSession; + import javax.media.*; import javax.media.control.TrackControl; import javax.media.control.PacketSizeControl; @@ -71,24 +73,26 @@ public class AudioChannel { private List sendStreams = new ArrayList(); + private JingleMediaSession jingleMediaSession; + private boolean started = false; /** * Creates an Audio Channel for a desired jmf locator. For instance: new MediaLocator("dsound://") * - * @param locator media locator - * @param localIpAddress local IP address - * @param remoteIpAddress remote IP address - * @param localPort local port number - * @param remotePort remote port number - * @param format audio format + * @param locator media locator + * @param localIpAddress local IP address + * @param remoteIpAddress remote IP address + * @param localPort local port number + * @param remotePort remote port number + * @param format audio format */ public AudioChannel(MediaLocator locator, String localIpAddress, String remoteIpAddress, int localPort, int remotePort, - Format format) { + Format format, JingleMediaSession jingleMediaSession) { this.locator = locator; this.localIpAddress = localIpAddress; @@ -96,7 +100,7 @@ public class AudioChannel { this.localPort = localPort; this.portBase = remotePort; this.format = format; - + this.jingleMediaSession = jingleMediaSession; } /** @@ -323,7 +327,7 @@ public class AudioChannel { SessionAddress localAddr, destAddr; InetAddress ipAddr; SendStream sendStream; - audioReceiver = new AudioReceiver(this); + audioReceiver = new AudioReceiver(this,jingleMediaSession); int port; for (int i = 0; i < pbss.length; i++) { @@ -471,8 +475,8 @@ public class AudioChannel { try { localhost = InetAddress.getLocalHost(); - AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP)); - AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP)); + AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null); + AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null); audioChannel0.start(); audioChannel1.start(); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java index ce765e53c..e7361e861 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java @@ -82,7 +82,7 @@ public class AudioMediaSession extends JingleMediaSession { remotePort = this.getRemote().getPort(); } - audioChannel = new AudioChannel(new MediaLocator(this.getMediaLocator()), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType())); + audioChannel = new AudioChannel(new MediaLocator(this.getMediaLocator()), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType()),this); } /** @@ -156,4 +156,5 @@ public class AudioMediaSession extends JingleMediaSession { } return freePort; } + } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java index 72c0c2ce7..de718d7d2 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java @@ -20,6 +20,8 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf; +import org.jivesoftware.smackx.jingle.media.JingleMediaSession; + import javax.media.*; import javax.media.protocol.DataSource; import javax.media.rtp.*; @@ -28,7 +30,7 @@ import javax.media.rtp.event.*; /** * This class implements receive methods and listeners to be used in AudioChannel * - * @author Thiago Camargo + * @author Thiago Camargo */ public class AudioReceiver implements ReceiveStreamListener, SessionListener, ControllerListener { @@ -36,9 +38,11 @@ public class AudioReceiver implements ReceiveStreamListener, SessionListener, boolean dataReceived = false; Object dataSync; + JingleMediaSession jingleMediaSession; - public AudioReceiver(final Object dataSync) { + public AudioReceiver(final Object dataSync, final JingleMediaSession jingleMediaSession) { this.dataSync = dataSync; + this.jingleMediaSession = jingleMediaSession; } /** @@ -63,7 +67,8 @@ public class AudioReceiver implements ReceiveStreamListener, SessionListener, System.err.println(" - Received an RTP PayloadChangeEvent."); System.err.println("Sorry, cannot handle payload change."); - } else if (evt instanceof NewReceiveStreamEvent) { + } + else if (evt instanceof NewReceiveStreamEvent) { try { stream = evt.getReceiveStream(); @@ -71,9 +76,11 @@ public class AudioReceiver implements ReceiveStreamListener, SessionListener, // Find out the formats. RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); + jingleMediaSession.mediaReceived(participant!=null?participant.getCNAME():""); if (ctl != null) { System.err.println(" - Recevied new RTP stream: " + ctl.getFormat()); - } else + } + else System.err.println(" - Recevied new RTP stream"); if (participant == null) @@ -96,12 +103,14 @@ public class AudioReceiver implements ReceiveStreamListener, SessionListener, dataSync.notifyAll(); } - } catch (Exception e) { + } + catch (Exception e) { System.err.println("NewReceiveStreamEvent exception " + e.getMessage()); return; } - } else if (evt instanceof StreamMappedEvent) { + } + else if (evt instanceof StreamMappedEvent) { if (stream != null && stream.getDataSource() != null) { DataSource ds = stream.getDataSource(); @@ -112,7 +121,8 @@ public class AudioReceiver implements ReceiveStreamListener, SessionListener, System.err.println(" " + ctl.getFormat()); System.err.println(" had now been identified as sent by: " + participant.getCNAME()); } - } else if (evt instanceof ByeEvent) { + } + else if (evt instanceof ByeEvent) { System.err.println(" - Got \"bye\" from: " + participant.getCNAME()); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java index e49d540cd..59af7d403 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java @@ -44,6 +44,7 @@ public class BridgedTransportManager extends JingleTransportManager implements J /** * Return the correspondent resolver + * * @param session correspondent Jingle Session * @return resolver */ @@ -70,6 +71,10 @@ public class BridgedTransportManager extends JingleTransportManager implements J public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) { } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + // Session Created public void sessionCreated(JingleSession jingleSession) { diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java index b91ec9432..5efc35a8b 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java @@ -28,7 +28,7 @@ import org.jivesoftware.smackx.jingle.listeners.CreatedJingleSessionListener; */ public class ICETransportManager extends JingleTransportManager implements JingleSessionListener, CreatedJingleSessionListener { - ICEResolver iceResolver = null; + ICEResolver iceResolver = null; public ICETransportManager(XMPPConnection xmppConnection, String server, int port) { iceResolver = new ICEResolver(xmppConnection, server, port); @@ -53,7 +53,7 @@ public class ICETransportManager extends JingleTransportManager implements Jingl // Implement a Session Listener to relay candidates after establishment public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { - if (lc instanceof ICECandidate) { + if (lc instanceof ICECandidate) { if (((ICECandidate) lc).getType().equals("relay")) { RTPBridge rtpBridge = RTPBridge.relaySession(lc.getConnection(), lc.getSessionId(), lc.getPassword(), rc, lc); } @@ -72,6 +72,10 @@ public class ICETransportManager extends JingleTransportManager implements Jingl public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) { } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + // Session Created public void sessionCreated(JingleSession jingleSession) { diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java index f1bb34690..3895f18ce 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java @@ -375,6 +375,10 @@ public class JingleManagerTest extends SmackTestCase { + rc.getPort()); } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionRedirected(String redirection, JingleSession jingleSession) { } }); @@ -455,6 +459,10 @@ public class JingleManagerTest extends SmackTestCase { + rc.getPort()); } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionRedirected(String redirection, JingleSession jingleSession) { } }); @@ -496,6 +504,10 @@ public class JingleManagerTest extends SmackTestCase { public void sessionRedirected(String redirection, JingleSession jingleSession) { } + + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } }); session0.start(null); @@ -570,6 +582,10 @@ public class JingleManagerTest extends SmackTestCase { TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionRedirected(String redirection, JingleSession jingleSession) { } }); @@ -730,6 +746,10 @@ public class JingleManagerTest extends SmackTestCase { // incCounter(); } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) { // incCounter(); } @@ -766,6 +786,10 @@ public class JingleManagerTest extends SmackTestCase { // incCounter(); } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) { // incCounter(); } @@ -957,6 +981,10 @@ public class JingleManagerTest extends SmackTestCase { TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionRedirected(String redirection, JingleSession jingleSession) { } }); diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java index f2d8d8bc9..991a865c2 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java @@ -169,7 +169,7 @@ public class JingleMediaTest extends SmackTestCase { try { IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); try { - Thread.sleep(30000); + Thread.sleep(12000); } catch (InterruptedException e) { e.printStackTrace(); @@ -195,7 +195,7 @@ public class JingleMediaTest extends SmackTestCase { public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) { if (newOne != null) { if ((newOne instanceof OutgoingJingleSession.Active)) - System.err.println("|||"+newOne.getClass().getCanonicalName()+"|||"); + System.err.println("|||" + newOne.getClass().getCanonicalName() + "|||"); } } }); @@ -414,8 +414,8 @@ public class JingleMediaTest extends SmackTestCase { public void testAudioChannelOpenClose() { for (int i = 0; i < 5; i++) { try { - AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP)); - AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP)); + AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null); + AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null); audioChannel0.start(); audioChannel1.start(); @@ -446,8 +446,8 @@ public class JingleMediaTest extends SmackTestCase { public void testAudioChannelStartStop() { try { - AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP)); - AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP)); + AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null); + AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null); for (int i = 0; i < 5; i++) { diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java index 90ec9f523..ca656ebd2 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java @@ -301,6 +301,10 @@ public class STUNResolverTest extends SmackTestCase { public void sessionRedirected(String redirection, JingleSession jingleSession) { } + + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } }); session1.start(request); } @@ -336,6 +340,10 @@ public class STUNResolverTest extends SmackTestCase { + rc.getPort()); } + public void sessionMediaReceived(JingleSession jingleSession, String participant) { + // Do Nothing + } + public void sessionRedirected(String redirection, JingleSession jingleSession) { } });