/* This file is part of Peers, a java SIP softphone. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Copyright 2010-2013 Yohann Martineau */ package peers.media; import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import Audio.BassFileReader; import org.pmw.tinylog.Logger; import peers.rtp.RtpPacket; import peers.rtp.RtpSession; import peers.sdp.Codec; import peers.sip.core.useragent.UserAgent; public class MediaManager { public static final int DEFAULT_CLOCK = 8000; // Hz private UserAgent userAgent; private CaptureRtpSender captureRtpSender; private IncomingRtpReader incomingRtpReader; private RtpSession rtpSession; private DtmfFactory dtmfFactory; private DatagramSocket datagramSocket; //private FileReader fileReader; private BassFileReader fileReader; public MediaManager(UserAgent userAgent) { this.userAgent = userAgent; dtmfFactory = new DtmfFactory(); } private void startRtpSessionOnSuccessResponse(String localAddress, String remoteAddress, int remotePort, Codec codec, SoundSource soundSource) { InetAddress inetAddress; try { inetAddress = InetAddress.getByName(localAddress); } catch (UnknownHostException e) { Logger.error("unknown host: " + localAddress, e); return; } rtpSession = new RtpSession(inetAddress, datagramSocket, userAgent.isMediaDebug(), userAgent.getPeersHome()); try { inetAddress = InetAddress.getByName(remoteAddress); rtpSession.setRemoteAddress(inetAddress); } catch (UnknownHostException e) { Logger.error("unknown host: " + remoteAddress, e); } rtpSession.setRemotePort(remotePort); try { captureRtpSender = new CaptureRtpSender(rtpSession, soundSource, userAgent.isMediaDebug(), codec, userAgent.getPeersHome()); } catch (IOException e) { Logger.error("input/output error", e); return; } try { captureRtpSender.start(); } catch (IOException e) { Logger.error("input/output error", e); } } public void successResponseReceived(String localAddress, String remoteAddress, int remotePort, Codec codec) { switch (userAgent.getMediaMode()) { case captureAndPlayback: AbstractSoundManager soundManager = userAgent.getSoundManager(); soundManager.init(); startRtpSessionOnSuccessResponse(localAddress, remoteAddress, remotePort, codec, soundManager); try { incomingRtpReader = new IncomingRtpReader( captureRtpSender.getRtpSession(), soundManager, codec); } catch (IOException e) { Logger.error("input/output error", e); return; } incomingRtpReader.start(); break; case echo: Echo echo; try { echo = new Echo(datagramSocket, remoteAddress, remotePort); } catch (UnknownHostException e) { Logger.error("unknown host amongst " + localAddress + " or " + remoteAddress); return; } userAgent.setEcho(echo); Thread echoThread = new Thread(echo, Echo.class.getSimpleName()); echoThread.start(); break; case file: String fileName = userAgent.getConfig().getMediaFile(); //fileReader = new FileReader(fileName); fileReader = new BassFileReader(fileName,null); startRtpSessionOnSuccessResponse(localAddress, remoteAddress, remotePort, codec, fileReader); try { incomingRtpReader = new IncomingRtpReader( captureRtpSender.getRtpSession(), null, codec); } catch (IOException e) { Logger.error("input/output error", e); return; } incomingRtpReader.start(); break; case none: default: break; } } private void startRtpSession(String destAddress, int destPort, Codec codec, SoundSource soundSource) { rtpSession = new RtpSession(userAgent.getConfig() .getLocalInetAddress(), datagramSocket, userAgent.isMediaDebug(), userAgent.getPeersHome()); try { InetAddress inetAddress = InetAddress.getByName(destAddress); rtpSession.setRemoteAddress(inetAddress); } catch (UnknownHostException e) { Logger.error("unknown host: " + destAddress, e); } rtpSession.setRemotePort(destPort); try { captureRtpSender = new CaptureRtpSender(rtpSession, soundSource, userAgent.isMediaDebug(), codec, userAgent.getPeersHome()); } catch (IOException e) { Logger.error("input/output error", e); return; } try { captureRtpSender.start(); } catch (IOException e) { Logger.error("input/output error", e); } } public void handleAck(String destAddress, int destPort, Codec codec) { switch (userAgent.getMediaMode()) { case captureAndPlayback: AbstractSoundManager soundManager = userAgent.getSoundManager(); soundManager.init(); startRtpSession(destAddress, destPort, codec, soundManager); try { //FIXME RTP sessions can be different ! incomingRtpReader = new IncomingRtpReader(rtpSession, soundManager, codec); } catch (IOException e) { Logger.error("input/output error", e); return; } incomingRtpReader.start(); break; case echo: Echo echo; try { echo = new Echo(datagramSocket, destAddress, destPort); } catch (UnknownHostException e) { Logger.error("unknown host amongst " + userAgent.getConfig().getLocalInetAddress() .getHostAddress() + " or " + destAddress); return; } userAgent.setEcho(echo); Thread echoThread = new Thread(echo, Echo.class.getSimpleName()); echoThread.start(); break; case file: if (fileReader != null) { fileReader.close(); } String fileName = userAgent.getConfig().getMediaFile(); //fileReader = new FileReader(fileName); fileReader = new BassFileReader(fileName, null); startRtpSession(destAddress, destPort, codec, fileReader); try { incomingRtpReader = new IncomingRtpReader(rtpSession, null, codec); } catch (IOException e) { Logger.error("input/output error", e); return; } incomingRtpReader.start(); break; case none: default: break; } } public void updateRemote(String destAddress, int destPort, Codec codec) { switch (userAgent.getMediaMode()) { case captureAndPlayback: try { InetAddress inetAddress = InetAddress.getByName(destAddress); rtpSession.setRemoteAddress(inetAddress); } catch (UnknownHostException e) { Logger.error("unknown host: " + destAddress, e); } rtpSession.setRemotePort(destPort); break; case echo: //TODO update echo socket break; case file: try { InetAddress inetAddress = InetAddress.getByName(destAddress); rtpSession.setRemoteAddress(inetAddress); } catch (UnknownHostException e) { Logger.error("unknown host: " + destAddress, e); } rtpSession.setRemotePort(destPort); break; default: break; } } public void sendDtmf(char digit) { if (captureRtpSender != null) { List rtpPackets = dtmfFactory.createDtmfPackets(digit); RtpSender rtpSender = captureRtpSender.getRtpSender(); rtpSender.pushPackets(rtpPackets); } } public void stopSession() { if (rtpSession != null) { rtpSession.stop(); while (!rtpSession.isSocketClosed()) { try { Thread.sleep(15); } catch (InterruptedException e) { Logger.debug("sleep interrupted"); } } rtpSession = null; } if (incomingRtpReader != null) { incomingRtpReader = null; } if (captureRtpSender != null) { captureRtpSender.stop(); captureRtpSender = null; } if (datagramSocket != null) { datagramSocket = null; } switch (userAgent.getMediaMode()) { case captureAndPlayback: AbstractSoundManager soundManager = userAgent.getSoundManager(); if (soundManager != null) { soundManager.close(); } break; case echo: Echo echo = userAgent.getEcho(); if (echo != null) { echo.stop(); userAgent.setEcho(null); } break; case file: fileReader.close(); break; default: break; } } public void setDatagramSocket(DatagramSocket datagramSocket) { this.datagramSocket = datagramSocket; } public DatagramSocket getDatagramSocket() { return datagramSocket; } // public FileReader getFileReader() { // return fileReader; // } public BassFileReader getFileReader() { return fileReader; } }