diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ClientConnectionManager.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ClientConnectionManager.java index 7a096b9152..0200b3dfbc 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ClientConnectionManager.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ClientConnectionManager.java @@ -1,7 +1,7 @@ package org.bigbluebutton.voiceconf.red5; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.service.IServiceCapableConnection; @@ -10,7 +10,7 @@ import org.slf4j.Logger; public class ClientConnectionManager { private static Logger log = Red5LoggerFactory.getLogger(ClientConnectionManager.class, "sip"); - private Map clients = new HashMap(); + private Map clients = new ConcurrentHashMap(); public void createClient(String id, IServiceCapableConnection connection) { ClientConnection cc = new ClientConnection(id, connection); @@ -22,5 +22,15 @@ public class ClientConnectionManager { if (cc == null) log.warn("Failed to remove client {}.", id); } + public void joinConferenceSuccess(String clientId, String usertalkStream, String userListenStream) { + + } + public void joinConferenceFailed(String clientId) { + + } + + public void leaveConference(String clientId) { + + } } diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java index 2ca91ec29f..d44c624f6c 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java @@ -2,7 +2,6 @@ package org.bigbluebutton.voiceconf.red5.media; import java.net.DatagramSocket; import java.net.SocketException; - import org.bigbluebutton.voiceconf.red5.media.transcoder.NellyToPcmTranscoder; import org.bigbluebutton.voiceconf.red5.media.transcoder.PcmToNellyTranscoder; import org.bigbluebutton.voiceconf.red5.media.transcoder.SpeexToSpeexTranscoder; @@ -19,8 +18,8 @@ public class CallStream implements StreamObserver { private final static Logger log = Red5LoggerFactory.getLogger(CallStream.class, "sip"); private DatagramSocket socket = null; - private FlashToSipAudioStream talkStream; - private SipToFlashAudioStream listenStream; + private FlashToSipAudioStream userTalkStream; + private SipToFlashAudioStream userListenStream; private final Codec sipCodec; private final SipConnectInfo connInfo; private final IScope scope; @@ -42,40 +41,35 @@ public class CallStream implements StreamObserver { Transcoder rtmpToRtpTranscoder, rtpToRtmpTranscoder; if (sipCodec.getCodecId() == SpeexCodec.codecId) { rtmpToRtpTranscoder = new SpeexToSpeexTranscoder(sipCodec); - rtpToRtmpTranscoder = new SpeexToSpeexTranscoder(sipCodec, listenStream); + rtpToRtmpTranscoder = new SpeexToSpeexTranscoder(sipCodec, userListenStream); } else { rtmpToRtpTranscoder = new NellyToPcmTranscoder(sipCodec); - rtpToRtmpTranscoder = new PcmToNellyTranscoder(sipCodec, listenStream); + rtpToRtmpTranscoder = new PcmToNellyTranscoder(sipCodec, userListenStream); } - listenStream = new SipToFlashAudioStream(scope, rtpToRtmpTranscoder, socket); - listenStream.addListenStreamObserver(this); - talkStream = new FlashToSipAudioStream(rtmpToRtpTranscoder, socket, connInfo); + userListenStream = new SipToFlashAudioStream(scope, rtpToRtmpTranscoder, socket); + userListenStream.addListenStreamObserver(this); + userTalkStream = new FlashToSipAudioStream(rtmpToRtpTranscoder, socket, connInfo); } public String getTalkStreamName() { - return talkStream.getStreamName(); + return userTalkStream.getStreamName(); } public String getListenStreamName() { - return listenStream.getStreamName(); - } - - public void sendSipDtmfDigits(String argDigits) throws StreamException { - if (talkStream != null) - talkStream.sendDtmfDigits(argDigits); + return userListenStream.getStreamName(); } public void startTalkStream(IBroadcastStream broadcastStream, IScope scope) throws StreamException { - talkStream.start(broadcastStream, scope); + userTalkStream.start(broadcastStream, scope); } public void stopTalkStream(IBroadcastStream broadcastStream, IScope scope) { - talkStream.stop(broadcastStream, scope); + userTalkStream.stop(broadcastStream, scope); } public void stop() { - listenStream.stop(); + userListenStream.stop(); } @Override diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java index 8f362097c2..ccccce6c8c 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java @@ -60,11 +60,7 @@ public class FlashToSipAudioStream { public void stop(IBroadcastStream broadcastStream, IScope scope) { broadcastStream.removeStreamListener(mInputListener); } - - public void sendDtmfDigits(String dtmfDigits) throws StreamException { - rtpSender.sendDtmfDigits(dtmfDigits); - } - + public String getStreamName() { return talkStreamName; } diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java index 951113b460..115d461de4 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java @@ -76,5 +76,6 @@ public class RtpStreamReceiver { } log.debug("Rtp Receiver stopped." ); log.debug("Packet Received = " + packetReceivedCounter + "." ); + if (listener != null) listener.onStoppedReceiving(); } } diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamSender.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamSender.java index 5efd5ede76..fde9a4c7e4 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamSender.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamSender.java @@ -55,66 +55,6 @@ public class RtpStreamSender { timestamp = 0; } - public void sendDtmfDigits(String dtmfDigits) throws StreamException { - byte[] dtmfbuf = new byte[transcoder.getOutgoingEncodedFrameSize() + RTP_HEADER_SIZE]; - RtpPacket dtmfpacket = new RtpPacket(dtmfbuf, 0); - dtmfpacket.setPayloadType(DTMF2833); - dtmfpacket.setPayloadLength(transcoder.getOutgoingEncodedFrameSize()); - - byte[] blankbuf = new byte[transcoder.getOutgoingEncodedFrameSize() + RTP_HEADER_SIZE]; - RtpPacket blankpacket = new RtpPacket(blankbuf, 0); - blankpacket.setPayloadType(transcoder.getCodecId()); - blankpacket.setPayloadLength(transcoder.getOutgoingEncodedFrameSize()); - - for (int d = 0; d < dtmfDigits.length(); d++) { - char digit = dtmfDigits.charAt(d); - if (digit == '*') { - dtmfbuf[startPayloadPos] = 10; - } - else if (digit == '#') { - dtmfbuf[startPayloadPos] = 11; - } - else if (digit >= 'A' && digit <= 'D') { - dtmfbuf[startPayloadPos] = (byte) (digit - 53); - } - else { - dtmfbuf[startPayloadPos] = (byte) (digit - 48); - } - - // notice we are bumping times/seqn just like audio packets - // send start event packet 3 times - dtmfbuf[startPayloadPos + 1] = 0; // start event flag and volume - dtmfbuf[startPayloadPos + 2] = 1; // duration 8 bits - dtmfbuf[startPayloadPos + 3] = -32; // duration 8 bits - - for (int r = 0; r < 3; r++) { - dtmfpacket.setSequenceNumber(sequenceNum++); - dtmfpacket.setTimestamp(transcoder.getOutgoingEncodedFrameSize()); - doRtpDelay(); - rtpSocketSend(dtmfpacket); - } - - // send end event packet 3 times - dtmfbuf[startPayloadPos + 1] = -128; // end event flag - dtmfbuf[startPayloadPos + 2] = 3; // duration 8 bits - dtmfbuf[startPayloadPos + 3] = 116; // duration 8 bits - for (int r = 0; r < 3; r++) { - dtmfpacket.setSequenceNumber(sequenceNum++); - dtmfpacket.setTimestamp(transcoder.getOutgoingEncodedFrameSize() ); - doRtpDelay(); - rtpSocketSend(dtmfpacket); - } - - // send 200 ms of blank packets - for (int r = 0; r < 200 / transcoder.getOutgoingPacketization(); r++) { - blankpacket.setSequenceNumber(sequenceNum++); - blankpacket.setTimestamp(transcoder.getOutgoingEncodedFrameSize()); - doRtpDelay(); - rtpSocketSend(blankpacket); - } - } - } - public void send(byte[] audioData, int offset, int num) { transcoder.transcode(audioData, offset, num, transcodedAudioDataBuffer, RTP_HEADER_SIZE, this); } @@ -127,13 +67,6 @@ public class RtpStreamSender { rtpSocketSend(rtpPacket); } - private void doRtpDelay() { - try { - Thread.sleep(transcoder.getOutgoingPacketization() - 2); - } catch (Exception e) { - } - } - private synchronized void rtpSocketSend(RtpPacket rtpPacket) throws StreamException { try { rtpSocket.send(rtpPacket); diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java index beca81fd2b..9eea1afd7d 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java @@ -1,7 +1,6 @@ package org.bigbluebutton.voiceconf.red5.media; import java.net.DatagramSocket; - import org.bigbluebutton.voiceconf.red5.media.transcoder.TranscodedAudioDataListener; import org.bigbluebutton.voiceconf.red5.media.transcoder.Transcoder; import org.red5.logging.Red5LoggerFactory; @@ -25,6 +24,7 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt public SipToFlashAudioStream(IScope scope, Transcoder transcoder, DatagramSocket socket) { this.scope = scope; rtpStreamReceiver = new RtpStreamReceiver(transcoder, socket); + rtpStreamReceiver.setRtpStreamReceiverListener(this); listenStreamName = "speaker_" + System.currentTimeMillis(); scope.setName(listenStreamName); } @@ -77,6 +77,6 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt @Override public void onStoppedReceiving() { - if (observer != null) observer.listenStreamStopped(); + if (observer != null) observer.onStreamStopped(); } } diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java index 0e624338b5..7e51bded96 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java @@ -9,6 +9,7 @@ import org.zoolu.sdp.*; import org.bigbluebutton.voiceconf.red5.CallStreamFactory; import org.bigbluebutton.voiceconf.red5.ClientConnectionManager; import org.bigbluebutton.voiceconf.red5.media.CallStream; +import org.bigbluebutton.voiceconf.red5.media.StreamException; import org.bigbluebutton.voiceconf.red5.media.StreamObserver; import org.red5.app.sip.codecs.Codec; import org.red5.app.sip.codecs.CodecUtils; @@ -31,8 +32,6 @@ public class CallAgent extends CallListenerAdapter { private CallStream callStream; private String localSession = null; private Codec sipCodec = null; - private Set listeners = new HashSet(); - private CallStreamFactory callStreamFactory; private ClientConnectionManager clientConnManager; @@ -60,14 +59,6 @@ public class CallAgent extends CallListenerAdapter { return clientId; } - public void addListener(SipUserAgentListener listener) { - listeners.add(listener); - } - - public void removeListener(SipUserAgentListener listener) { - listeners.remove(listener); - } - private void changeStatus(CallState state) { callState = state; } @@ -76,10 +67,6 @@ public class CallAgent extends CallListenerAdapter { return callState == CallState.UA_IDLE; } - public void sendDtmfDigits(String digits) { - callStream.sendDtmfDigits(digits); - } - private void initSessionDescriptor() { log.debug("initSessionDescriptor"); SessionDescriptor newSdp = SdpUtils.createInitialSdp(userProfile.username, @@ -120,9 +107,8 @@ public class CallAgent extends CallListenerAdapter { } private void createVoiceStreams() { - // Exit if the Media Application is already running. if (callStream != null) { - log.debug("launchMediaApplication", "Media application is already running."); + log.debug("Media application is already running."); return; } @@ -184,7 +170,12 @@ public class CallAgent extends CallListenerAdapter { } public void startTalkStream(IBroadcastStream broadcastStream, IScope scope) { - callStream.startTalkStream(broadcastStream, scope); + try { + callStream.startTalkStream(broadcastStream, scope); + } catch (StreamException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } public void stopTalkStream(IBroadcastStream broadcastStream, IScope scope) { @@ -237,7 +228,7 @@ public class CallAgent extends CallListenerAdapter { * The user has managed to join the conference. */ public void onCallAccepted(Call call, String sdp, Message resp) { - log.debug( "onCallAccepted"); + log.debug("Received 200/OK. So user has successfully joined the conference."); if (!isCurrentCall(call)) return; log.debug("ACCEPTED/CALL."); @@ -251,7 +242,6 @@ public class CallAgent extends CallListenerAdapter { } createVoiceStreams(); - notifyListenersOfOnOutgoingCallAccepted(); } public void notifyListenersOfOnOutgoingCallAccepted() { @@ -262,7 +252,7 @@ public class CallAgent extends CallListenerAdapter { /** Callback function called when arriving an ACK method (call confirmed) */ public void onCallConfirmed(Call call, String sdp, Message ack) { - log.debug("onCallConfirmed"); + log.debug("Received ACK. Hmmm...is this for when the server initiates the call????"); if (!isCurrentCall(call)) return; @@ -307,11 +297,11 @@ public class CallAgent extends CallListenerAdapter { * Callback function that may be overloaded (extended). Called when arriving a CANCEL request */ public void onCallCanceling(Call call, Message cancel) { - log.debug("onCallCanceling"); + log.error("Server shouldn't cancel call...or does it???"); if (!isCurrentCall(call)) return; - log.debug("CANCEL."); + log.debug("Server has CANCEL-led the call."); changeStatus(CallState.UA_IDLE); notifyListenersOfOnIncomingCallCancelled(); }