/** * $RCSfile: ,v $ * $Revision: $ * $Date: $ * * Copyright (C) 2004-2011 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 net.java.sipmack.sip; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.media.rtp.ReceiveStreamListener; import javax.media.rtp.event.ReceiveStreamEvent; import javax.sdp.SdpFactory; import javax.sdp.SdpParseException; import javax.sdp.SessionDescription; import javax.sip.Dialog; import javax.sip.address.Address; import javax.sip.address.SipURI; import javax.sip.address.URI; import javax.sip.header.FromHeader; import javax.sip.header.ToHeader; import javax.sip.message.Request; import net.java.sipmack.common.Log; import net.java.sipmack.media.AudioMediaSession; import net.java.sipmack.media.AudioReceiverChannel; import net.java.sipmack.sip.event.CallListener; import net.java.sipmack.sip.event.CallStateEvent; /** * Title: SIPark * Description:JAIN-SIP Audio/Video phone application * * @author Thiago Camargo (http://www.jivesoftware.com) * @version 1.2 */ public class Call implements ReceiveStreamListener { public static final String DIALING = "Discando"; public static final String RINGING = "Tocando"; public static final String ALERTING = "Chamando"; public static final String CONNECTED = "Conectado"; public static final String DISCONNECTED = "Desconectado"; public static final String BUSY = "Ocupado"; public static final String FAILED = "Falha"; public static final String MOVING_LOCALLY = "Moving Locally"; public static final String MOVING_REMOTELY = "Moving Remotely"; public static final String RECONNECTED = "reConnected"; private long start = 0; private Dialog dialog = null; private SessionDescription localSdpDescription = null; private SessionDescription remoteSdpDescription = null; private boolean holdCam = false; private boolean holdMic = false; private AudioMediaSession audioMediaSession = null; private AudioReceiverChannel audioReceiverChannel = null; /** * While in its early state the dialog cannot provide us with its * corresponding transaction as it is not yet created That's where the * initialRequest field comes in. */ private Request initialRequest = null; /** */ private Request lastRequest = null; private String callState = ""; // Event Management List<CallListener> listeners = new CopyOnWriteArrayList<CallListener>(); public SessionDescription getLocalSdpDescription() { return localSdpDescription; } public void setLocalSdpDescription(SessionDescription localSdpDescription) { this.localSdpDescription = localSdpDescription; } public AudioReceiverChannel getAudioReceiverChannel() { return audioReceiverChannel; } public void setAudioReceiverChannel(AudioReceiverChannel audioReceiverChannel) { this.audioReceiverChannel = audioReceiverChannel; } public String getState() { return callState; } public int getElapsedTime() { if (start == 0) return 0; return Math.round((System.currentTimeMillis() - start) / 1000); } public void start() { start = System.currentTimeMillis(); } public boolean isIncoming() { // Let it throw a null pointer exception if necessary return dialog.isServer(); } /** * @param dialog The dialog to set. */ void setDialog(Dialog dialog) { this.dialog = dialog; } /** * @return Returns the dialog. */ Dialog getDialog() { return dialog; } // SDP Data /** * Set remote SDP Description of this call * * @param data the remoteSdpDescription to set. */ void setRemoteSdpDescription(SessionDescription data) { this.remoteSdpDescription = data; } /** * Set remote SDP Description of this call * * @param data the remoteSdpDescription to set. */ void setRemoteSdpDescription(String data) { if (data == null || data.equals("")) return; try { this.remoteSdpDescription = SdpFactory.getInstance().createSessionDescription(data); } catch (SdpParseException e) { e.printStackTrace(); } } /** * Get remote SDP Description of this call * * @return Returns the remoteSdpDescription. */ public SessionDescription getRemoteSdpDescription() { return remoteSdpDescription; } public void setState(String newStatus) { if (newStatus.equals(getState())) return; String oldStatus = callState; this.callState = newStatus; fireCallStatusChangedEvent(oldStatus); } public String getAddress() { if (dialog.getState() != null) { return dialog.getRemoteParty().getURI().toString(); } else { if (dialog.isServer()) { FromHeader fromHeader = (FromHeader)initialRequest .getHeader(FromHeader.NAME); return fromHeader.getAddress().getURI().toString(); } else { ToHeader toHeader = (ToHeader)initialRequest .getHeader(ToHeader.NAME); return toHeader.getAddress().getURI().toString(); } } } public String getNumber() { return getAddress().split(":")[1].split("@")[0]; } public String getRemoteName() { Address address; if (dialog.getState() != null) { address = dialog.getRemoteParty(); } else { if (dialog.isServer()) { FromHeader fromHeader = (FromHeader)initialRequest .getHeader(FromHeader.NAME); address = fromHeader.getAddress(); } else { ToHeader toHeader = (ToHeader)initialRequest .getHeader(ToHeader.NAME); address = toHeader.getAddress(); } } String retVal = null; if (address.getDisplayName() != null && address.getDisplayName().trim().length() > 0) { retVal = address.getDisplayName(); } else { URI uri = address.getURI(); if (uri.isSipURI()) { retVal = ((SipURI)uri).getUser(); } } return retVal == null ? "" : retVal; } public int getID() { return hashCode(); } /** * Set Initial request of this call * * @param initialRequest The initialRequest to set. */ void setInitialRequest(Request initialRequest) { this.initialRequest = initialRequest; this.lastRequest = initialRequest; } /** * Get Initial request of this call * * @return Returns the initialRequest. */ public Request getInitialRequest() { return this.initialRequest; } /** * Set the last request of this call * * @param lastRequest The lastRequest to set. */ void setLastRequest(Request lastRequest) { this.lastRequest = lastRequest; } /** * Get last request of this call * * @return Returns the lastRequest. */ public Request getLastRequest() { return this.lastRequest; } String getDialogID() { return dialog.getDialogId(); } public String toString() { return "[ Call " + getID() + "\nde " + getRemoteName() + "@" + getAddress() + "\nSDP:" + getRemoteSdpDescription() + "]"; } public boolean onHoldMic() { return holdMic; } public boolean onHoldCam() { return holdCam; } public void onHoldMic(boolean h) { holdMic = h; } public void onHoldCam(boolean h) { holdCam = h; } // ====================== EVENTS =========================== public void addStateChangeListener(CallListener listener) { Log.debug(listener.getClass().getCanonicalName()); listeners.add(listener); } public void fireCallStatusChangedEvent(String oldStatus) { Log.debug(this.getState()); CallStateEvent evt = new CallStateEvent(this); evt.setOldState(oldStatus); for (CallListener callListener : listeners) { callListener.callStateChanged(evt); } } public AudioMediaSession getAudioMediaSession() { return audioMediaSession; } public void setAudioMediaSession(AudioMediaSession audioMediaSession) { this.audioMediaSession = audioMediaSession; } // ====================== RECEIVE STREAMS EVENTS ========================== public void update(ReceiveStreamEvent receiveStreamEvent) { } }