Improves DTMF configuration (auto, RTP, SIP INFO or INBAND). Creates a common interface for starting and stopping (RTP or INBAND) DTMF tones into AudioMediaStream interface and its implementation. Reverting DtmfTransformEngine to use previous threaded DTMFDispatcher.

cusax-fix
Vincent Lucas 14 years ago
parent 50ace9f09b
commit 9c0340f06d

@ -934,6 +934,10 @@ plugin.sipaccregwizz.KEEP_ALIVE_METHOD=Keep alive method
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL=Keep alive interval
plugin.sipaccregwizz.KEEP_ALIVE_INTERVAL_INFO=Between 1 and 3600 seconds
plugin.sipaccregwizz.DTMF_METHOD=DTMF method
plugin.sipaccregwizz.DTMF_AUTO=Auto: Choose automatically between RTP and Inband (no SIP INFO)
plugin.sipaccregwizz.DTMF_RTP=RTP ( RFC2833 / RFC 4733 )
plugin.sipaccregwizz.DTMF_SIP_INFO=SIP INFO
plugin.sipaccregwizz.DTMF_INBAND=Inband
plugin.sipaccregwizz.REGISTER=REGISTER
plugin.sipaccregwizz.OVERRIDE_SERVER_DEFAULT_OPTIONS=Override server default options
plugin.sipaccregwizz.ENABLE_DEFAULT_ENCRYPTION=Enable support to encrypt calls

@ -17,6 +17,7 @@
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.service.neomedia.event.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
/**
@ -257,22 +258,47 @@ public void removeDTMFListener(DTMFListener listener)
/**
* Starts sending the specified <tt>DTMFTone</tt> until the
* <tt>stopSendingDTMF()</tt> method is called. Callers should keep in mind
* the fact that calling this method would most likely interrupt all audio
* transmission until the corresponding stop method is called. Also, calling
* this method successively without invoking the corresponding stop method
* between the calls will simply replace the <tt>DTMFTone</tt> from the
* first call with that from the second.
* <tt>stopSendingDTMF()</tt> method is called (Excepts for INBAND DTMF,
* which stops by itself this is why where there is no need to call the
* stopSendingDTMF). Callers should keep in mind the fact that calling this
* method would most likely interrupt all audio transmission until the
* corresponding stop method is called. Also, calling this method
* successively without invoking the corresponding stop method between the
* calls will simply replace the <tt>DTMFTone</tt> from the first call with
* that from the second.
*
* @param tone the <tt>DTMFTone</tt> to start sending
* @see AudioMediaStream#startSendingDTMF(DTMFTone)
* @param tone the <tt>DTMFTone</tt> to start sending.
* @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND).
*
* @see AudioMediaStream#startSendingDTMF(DTMFTone, DTMFEnum)
*/
public void startSendingDTMF(DTMFTone tone)
public void startSendingDTMF(DTMFTone tone, DTMFEnum dtmfMethod)
{
if(dtmfTransfrmEngine == null)
return;
dtmfTransfrmEngine.startSending(tone);
switch(dtmfMethod)
{
case RTP_DTMF:
if(dtmfTransfrmEngine != null)
{
DTMFRtpTone t = DTMFRtpTone.mapTone(tone);
if(t != null)
{
dtmfTransfrmEngine.startSending(t);
}
}
break;
case SIP_INFO_DTMF:
// This kind of DTMF is not manged directly by the
// OperationSetDTMFSipImpl.
break;
case INBAND_DTMF:
MediaDeviceSession deviceSession = getDeviceSession();
if (deviceSession != null)
{
deviceSession.addDTMF(DTMFInbandTone.mapTone(tone));
}
break;
}
}
/**
@ -280,28 +306,28 @@ public void startSendingDTMF(DTMFTone tone)
* <tt>startSendingDTMF()</tt> method. Has no effect if no tone is currently
* being sent.
*
* @see AudioMediaStream#stopSendingDTMF()
*/
public void stopSendingDTMF()
{
if(dtmfTransfrmEngine == null)
return;
dtmfTransfrmEngine.stopSendingDTMF();
}
/**
* Adds a new inband DTMF tone to send.
* @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND).
*
* @param tone the DTMF tone to send.
* @see AudioMediaStream#stopSendingDTMF(DTMFEnum)
*/
public void addInbandDTMF(DTMFInbandTone tone)
public void stopSendingDTMF(DTMFEnum dtmfMethod)
{
MediaDeviceSession deviceSession = getDeviceSession();
if (deviceSession != null)
switch(dtmfMethod)
{
deviceSession.addDTMF(tone);
case RTP_DTMF:
if(dtmfTransfrmEngine != null)
{
dtmfTransfrmEngine.stopSendingDTMF();
}
break;
case SIP_INFO_DTMF:
// The SIP-INFO DTMF is not manged directly by the
// OperationSetDTMFSipImpl.
break;
case INBAND_DTMF:
// The INBAND DTMF is send by impluse of constant duration and
// does not need to be stopped explecitely.
break;
}
}
@ -407,7 +433,7 @@ public void fireConferenceAudioLevelEvent(final long[] audioLevels)
* @param tone the new tone
* @param end is end or start of tone.
*/
public void fireDTMFEvent(DTMFTone tone, boolean end)
public void fireDTMFEvent(DTMFRtpTone tone, boolean end)
{
Iterator<DTMFListener> iter = dtmfListeners.iterator();
DTMFToneEvent ev = new DTMFToneEvent(this, tone);

@ -44,7 +44,7 @@ private enum ToneTransmissionState
/**
* Indicates that the user has just called the {@link
* #startSending(DTMFTone)} method and we haven't yet sent any of the
* #startSending(DTMFRtpTone)} method and we haven't yet sent any of the
* packets corresponding to that particular tone.
*/
SEND_PENDING,
@ -72,13 +72,19 @@ private enum ToneTransmissionState
/**
* Array of all supported tones.
*/
private static final DTMFTone[] supportedTones =
new DTMFTone[]
{DTMFTone.DTMF_0, DTMFTone.DTMF_1, DTMFTone.DTMF_2, DTMFTone.DTMF_3,
DTMFTone.DTMF_4, DTMFTone.DTMF_5, DTMFTone.DTMF_6, DTMFTone.DTMF_7,
DTMFTone.DTMF_8, DTMFTone.DTMF_9, DTMFTone.DTMF_A, DTMFTone.DTMF_B,
DTMFTone.DTMF_C, DTMFTone.DTMF_D,
DTMFTone.DTMF_SHARP, DTMFTone.DTMF_STAR};
private static final DTMFRtpTone[] supportedTones =
new DTMFRtpTone[]
{DTMFRtpTone.DTMF_0, DTMFRtpTone.DTMF_1, DTMFRtpTone.DTMF_2,
DTMFRtpTone.DTMF_3, DTMFRtpTone.DTMF_4, DTMFRtpTone.DTMF_5,
DTMFRtpTone.DTMF_6, DTMFRtpTone.DTMF_7, DTMFRtpTone.DTMF_8,
DTMFRtpTone.DTMF_9, DTMFRtpTone.DTMF_A, DTMFRtpTone.DTMF_B,
DTMFRtpTone.DTMF_C, DTMFRtpTone.DTMF_D, DTMFRtpTone.DTMF_SHARP,
DTMFRtpTone.DTMF_STAR};
/**
* The dispatcher that is delivering tones to the media steam.
*/
private DTMFDispatcher dtmfDispatcher = null;
/**
* The status that this engine is currently in.
@ -89,7 +95,7 @@ private enum ToneTransmissionState
/**
* The tone that we are supposed to be currently transmitting.
*/
private DTMFTone currentTone = null;
private DTMFRtpTone currentTone = null;
/**
* The duration (in timestamp units or in other words ms*8) that we have
@ -181,7 +187,13 @@ public RawPacket reverseTransform(RawPacket pkt)
if(currentDtmfPayload == pkt.getPayloadType())
{
DtmfRawPacket p = new DtmfRawPacket(pkt);
this.addTonePacket(p);
if (dtmfDispatcher == null)
{
dtmfDispatcher = new DTMFDispatcher();
new Thread(dtmfDispatcher).start();
}
dtmfDispatcher.addTonePacket(p);
// ignore received dtmf packets
// if jmf receive change in rtp payload stops reception
@ -293,7 +305,7 @@ else if(toneTransmissionState == ToneTransmissionState.END_SEQUENCE_INITIATED)
*
* @param tone the tone that we'd like to start sending.
*/
public void startSending(DTMFTone tone)
public void startSending(DTMFRtpTone tone)
{
if(toneTransmissionState != ToneTransmissionState.IDLE)
throw new IllegalStateException(
@ -304,7 +316,7 @@ public void startSending(DTMFTone tone)
}
/**
* Interrupts transmission of a <tt>DTMFTone</tt> started with the
* Interrupts transmission of a <tt>DTMFRtpTone</tt> started with the
* <tt>startSendingDTMF()</tt> method. Has no effect if no tone is currently
* being sent.
*
@ -316,33 +328,132 @@ public void stopSendingDTMF()
}
/**
* A packet that we should convert to tone and deliver
* to our media stream and its listeners in a separate thread.
*
* @param p the packet we will convert and deliver.
* Stops threads that this transform engine is using for even delivery.
*/
private void addTonePacket(DtmfRawPacket p)
public void stop()
{
DTMFTone tone = getToneFromPacket(p);
boolean toEnd = p.isEnd();
mediaStream.fireDTMFEvent(tone, toEnd);
if(dtmfDispatcher != null)
dtmfDispatcher.stop();
}
/**
* Maps DTMF packet codes to our DTMFTone objects.
* @param p the packet
* @return the corresponding tone.
* A simple thread that waits for new tones to be reported from incoming
* RTP packets and then delivers them to the <tt>AudioMediaStream</tt>
* associated with this engine. The reason we need to do this in a separate
* thread is of course the time sensitive nature of incoming RTP packets.
*/
private DTMFTone getToneFromPacket(DtmfRawPacket p)
private class DTMFDispatcher
implements Runnable
{
for (int i = 0; i < supportedTones.length; i++)
/** Indicates whether this thread is supposed to be running */
private boolean isRunning = false;
/** The tone that we last received from the reverseTransform thread*/
private DTMFRtpTone lastReceivedTone = null;
/** The tone that we last received from the reverseTransform thread*/
private DTMFRtpTone lastReportedTone = null;
/**
* Have we received end of the currently started tone.
*/
private boolean toEnd = false;
/**
* Waits for new tone to be reported via the <tt>addTonePacket()</tt>
* method and then delivers them to the <tt>AudioMediaStream</tt> that
* we are associated with.
*/
public void run()
{
DTMFTone t = supportedTones[i];
if(t.getCode() == p.getCode())
return t;
isRunning = true;
DTMFRtpTone temp = null;
while(isRunning)
{
synchronized(this)
{
if(lastReceivedTone == null)
{
try
{
wait();
}
catch (InterruptedException ie) {}
}
temp = lastReceivedTone;
// make lastReportedLevels to null
// so we will wait for the next tone on next iteration
lastReceivedTone = null;
}
if(temp != null
&& ((lastReportedTone == null && !toEnd)
|| (lastReportedTone != null && toEnd)))
{
//now notify our listener
if (mediaStream != null)
{
mediaStream.fireDTMFEvent(temp, toEnd);
if(toEnd)
lastReportedTone = null;
else
lastReportedTone = temp;
toEnd = false;
}
}
}
}
return null;
/**
* A packet that we should convert to tone and deliver
* to our media stream and its listeners in a separate thread.
*
* @param p the packet we will convert and deliver.
*/
public void addTonePacket(DtmfRawPacket p)
{
synchronized(this)
{
this.lastReceivedTone = getToneFromPacket(p);
this.toEnd = p.isEnd();
notifyAll();
}
}
/**
* Causes our run method to exit so that this thread would stop
* handling levels.
*/
public void stop()
{
synchronized(this)
{
this.lastReceivedTone = null;
isRunning = false;
notifyAll();
}
}
/**
* Maps DTMF packet codes to our DTMFRtpTone objects.
* @param p the packet
* @return the corresponding tone.
*/
private DTMFRtpTone getToneFromPacket(DtmfRawPacket p)
{
for (int i = 0; i < supportedTones.length; i++)
{
DTMFRtpTone t = supportedTones[i];
if(t.getCode() == p.getCode())
return t;
}
return null;
}
}
}

@ -13,35 +13,32 @@
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.format.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.DTMFTone;
import net.java.sip.communicator.util.*;
/**
* Class responsible for sending a DTMF Tone using SIP INFO or using rfc4733.
*
* @author JM HEITZ
* @author Vincent Lucas
*/
public class OperationSetDTMFSipImpl
implements OperationSetDTMF
{
/**
* The DTMF method used to send tones.
* Our class logger.
*/
private String dtmfMethod = null;
private static final Logger logger
= Logger.getLogger(OperationSetDTMFSipImpl.class);
/**
* DTMF mode sending DTMF as sip info.
*/
private final DTMFInfo dtmfModeInfo;
/**
* DTMF sending rfc4733.
* The DTMF method used to send tones.
*/
private final DTMF4733 dtmfModeRFC4733;
private DTMFEnum dtmfMethod;
/**
* DTMF sending inband tones into the audio stream.
* DTMF mode sending DTMF as sip info.
*/
private final DTMFInband dtmfModeInband;
private final DTMFInfo dtmfModeInfo;
/**
* Constructor.
@ -50,16 +47,8 @@ public class OperationSetDTMFSipImpl
*/
public OperationSetDTMFSipImpl(ProtocolProviderServiceSipImpl pps)
{
AccountID accountID = pps.getAccountID();
this.dtmfMethod = accountID.getAccountPropertyString("DTMF_METHOD");
if(dtmfMethod == null)
{
accountID.putAccountProperty("DTMF_METHOD", "RFC4733 / SIP-INFO");
}
this.dtmfMethod = this.getDTMFMethod(pps);
dtmfModeInfo = new DTMFInfo(pps);
dtmfModeRFC4733 = new DTMF4733();
dtmfModeInband = new DTMFInband();
}
/**
@ -90,27 +79,41 @@ public synchronized void startSendingDTMF(CallPeer callPeer, DTMFTone tone)
CallPeerSipImpl cp = (CallPeerSipImpl) (callPeer);
if(this.dtmfMethod == null ||
this.dtmfMethod.equals("RFC4733 / SIP-INFO"))
// If this account is configured to use SIP-INFO DTMF.
if(this.dtmfMethod == DTMFEnum.SIP_INFO_DTMF)
{
if(isRFC4733Active(cp))
dtmfModeInfo.startSendingDTMF(cp, tone);
}
// Else sends DTMF (dtmfMethod defined as RTP or INBAND) via the
// AudioMediaStream interface.
else
{
DTMFEnum cpDTMFMethod = dtmfMethod;
// If "auto" DTMF mode selected, automatically selects RTP DTMF is
// telephon-event is available. Otherwise selects INBAND DMTF.
if(this.dtmfMethod == DTMFEnum.AUTO_DTMF)
{
dtmfModeRFC4733.startSendingDTMF(
((AudioMediaStream)cp.getMediaHandler()
.getStream(MediaType.AUDIO)),
tone);
if(isRFC4733Active(cp))
{
cpDTMFMethod = DTMFEnum.RTP_DTMF;
}
else
{
cpDTMFMethod = DTMFEnum.INBAND_DTMF;
}
}
else
// If the account is configured to use RTP DTMF method and the call
// does not manage telephone events. Then, we log it for futur
// debugging.
if(this.dtmfMethod == DTMFEnum.RTP_DTMF && !isRFC4733Active(cp))
{
dtmfModeInfo.startSendingDTMF(cp, tone);
logger.debug("RTP DTMF used without telephon-event capacities");
}
}
else
{
dtmfModeInband.addInbandDTMF(
((AudioMediaStream)cp.getMediaHandler()
.getStream(MediaType.AUDIO)),
tone);
((AudioMediaStream)cp.getMediaHandler().getStream(MediaType.AUDIO))
.startSendingDTMF(tone, cpDTMFMethod);
}
}
@ -132,19 +135,41 @@ public synchronized void stopSendingDTMF(CallPeer callPeer)
CallPeerSipImpl cp = (CallPeerSipImpl) (callPeer);
if(this.dtmfMethod == null ||
this.dtmfMethod.equals("RFC4733 / SIP-INFO"))
// If this account is configured to use SIP-INFO DTMF.
if(this.dtmfMethod == DTMFEnum.SIP_INFO_DTMF)
{
dtmfModeInfo.stopSendingDTMF(cp);
}
// Else sends DTMF (dtmfMethod defined as RTP or INBAND) via the
// AudioMediaStream interface.
else
{
if(isRFC4733Active(cp))
DTMFEnum cpDTMFMethod = dtmfMethod;
// If "auto" DTMF mode selected, automatically selects RTP DTMF is
// telephon-event is available. Otherwise selects INBAND DMTF.
if(this.dtmfMethod == DTMFEnum.AUTO_DTMF)
{
dtmfModeRFC4733.stopSendingDTMF(
((AudioMediaStream)cp.getMediaHandler()
.getStream(MediaType.AUDIO)));
if(isRFC4733Active(cp))
{
cpDTMFMethod = DTMFEnum.RTP_DTMF;
}
else
{
cpDTMFMethod = DTMFEnum.INBAND_DTMF;
}
}
else
// If the account is configured to use RTP DTMF method and the call
// does not manage telephone events. Then, we log it for futur
// debugging.
if(this.dtmfMethod == DTMFEnum.RTP_DTMF && !isRFC4733Active(cp))
{
dtmfModeInfo.stopSendingDTMF(cp);
logger.debug("RTP DTMF used without telephon-event capacities");
}
((AudioMediaStream)cp.getMediaHandler().getStream(MediaType.AUDIO))
.stopSendingDTMF(cpDTMFMethod);
}
}
@ -176,4 +201,50 @@ DTMFInfo getDtmfModeInfo()
{
return dtmfModeInfo;
}
/**
* Returns the corresponding DTMF method used for this account.
*
* @param pps the SIP Protocol provider service
*
* @return the DTMFEnum corresponding to the DTMF method set for this
* account.
*/
private DTMFEnum getDTMFMethod(ProtocolProviderServiceSipImpl pps)
{
AccountID accountID = pps.getAccountID();
String dtmfString = accountID.getAccountPropertyString("DTMF_METHOD");
// Verifies that the DTMF_METHOD property string is correctly set.
// If not, sets this account to the "auto" DTMF method and corrects the
// property string.
if(dtmfString == null
|| (!dtmfString.equals("AUTO_DTMF")
&& !dtmfString.equals("RTP_DTMF")
&& !dtmfString.equals("SIP_INFO_DTMF")
&& !dtmfString.equals("INBAND_DTMF")))
{
dtmfString = "AUTO_DTMF";
accountID.putAccountProperty("DTMF_METHOD", dtmfString);
}
if(dtmfString.equals("AUTO_DTMF"))
{
return DTMFEnum.AUTO_DTMF;
}
else if(dtmfString.equals("RTP_DTMF"))
{
return DTMFEnum.RTP_DTMF;
}
else if(dtmfString.equals("SIP_INFO_DTMF"))
{
return DTMFEnum.SIP_INFO_DTMF;
}
else // if(dtmfString.equals(INBAND_DTMF"))
{
return DTMFEnum.INBAND_DTMF;
}
}
}

@ -1,100 +0,0 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.sip.dtmf;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.DTMFTone;
/**
* Sending DTMFs through media service using rfc4733.
*
* @author Damian Minkov
*/
public class DTMF4733
{
/**
* Start sending DTMF.
* @param audioStream the stream of this call.
* @param tone
*/
public void startSendingDTMF(AudioMediaStream audioStream,
net.java.sip.communicator.service.protocol.DTMFTone tone)
{
DTMFTone t = mapTone(tone);
if(t != null)
audioStream.startSendingDTMF(t);
}
/**
* Stop sending current DTMF.
* @param audioStream
*/
public void stopSendingDTMF(AudioMediaStream audioStream)
{
audioStream.stopSendingDTMF();
}
/**
* Maps between protocol and media DTMF objects.
* @param tone
* @return
*/
private DTMFTone
mapTone(net.java.sip.communicator.service.protocol.DTMFTone tone)
{
if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_0))
return DTMFTone.DTMF_0;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_1))
return DTMFTone.DTMF_1;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_2))
return DTMFTone.DTMF_2;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_3))
return DTMFTone.DTMF_3;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_4))
return DTMFTone.DTMF_4;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_5))
return DTMFTone.DTMF_5;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_6))
return DTMFTone.DTMF_6;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_7))
return DTMFTone.DTMF_7;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_8))
return DTMFTone.DTMF_8;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_9))
return DTMFTone.DTMF_9;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_A))
return DTMFTone.DTMF_A;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_B))
return DTMFTone.DTMF_B;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_C))
return DTMFTone.DTMF_C;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_D))
return DTMFTone.DTMF_D;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_SHARP))
return DTMFTone.DTMF_SHARP;
else if(tone.equals(
net.java.sip.communicator.service.protocol.DTMFTone.DTMF_STAR))
return DTMFTone.DTMF_STAR;
return null;
}
}

@ -1,30 +0,0 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.sip.dtmf;
import net.java.sip.communicator.service.neomedia.*;
/**
* Sending DTMFs inband into the audio stream.
*
* @author Vincent Lucas
*/
public class DTMFInband
{
/**
* Adds a new inband DTMF tone to send.
*
* @param audioStream The stream of this call.
* @param tone The tone (audio signal) to send via the audioStream.
*/
public void addInbandDTMF(
AudioMediaStream audioStream,
net.java.sip.communicator.service.protocol.DTMFTone tone)
{
audioStream.addInbandDTMF(DTMFInbandTone.mapTone(tone));
}
}

@ -57,8 +57,14 @@ public class ConnectionPanel
private JComboBox dtmfMethodBox
= new JComboBox(new Object []
{
"RFC4733 / SIP-INFO",
"INBAND"
Resources.getString(
"plugin.sipaccregwizz.DTMF_AUTO"),
Resources.getString(
"plugin.sipaccregwizz.DTMF_RTP"),
Resources.getString(
"plugin.sipaccregwizz.DTMF_SIP_INFO"),
Resources.getString(
"plugin.sipaccregwizz.DTMF_INBAND")
});
private boolean isServerOverridden = false;
@ -527,10 +533,33 @@ String getDTMFMethod()
{
Object selItem = dtmfMethodBox.getSelectedItem();
if(selItem != null)
return selItem.toString();
else
// By default sets DTMF mezthod to auto.
if(selItem == null)
{
return null;
}
String selString = selItem.toString();
if(selString.equals(
Resources.getString("plugin.sipaccregwizz.DTMF_RTP")))
{
return "RTP_DTMF";
}
else if(selString.equals(
Resources.getString(
"plugin.sipaccregwizz.DTMF_SIP_INFO")))
{
return "SIP_INFO_DTMF";
}
else if(selString.equals(
Resources.getString("plugin.sipaccregwizz.DTMF_INBAND")))
{
return "INBAND_DTMF";
}
else
{
return "AUTO_DTMF";
}
}
/**
@ -545,7 +574,28 @@ void setDTMFMethod(String dtmfMethod)
}
else
{
dtmfMethodBox.setSelectedItem(dtmfMethod);
String selString;
if(dtmfMethod.equals("RTP_DTMF"))
{
selString =
Resources.getString("plugin.sipaccregwizz.DTMF_RTP");
}
else if(dtmfMethod.equals("SIP_INFO_DTMF"))
{
selString =
Resources.getString("plugin.sipaccregwizz.DTMF_SIP_INFO");
}
else if(dtmfMethod.equals("INBAND_DTMF"))
{
selString =
Resources.getString("plugin.sipaccregwizz.DTMF_INBAND");
}
else
{
selString =
Resources.getString("plugin.sipaccregwizz.DTMF_AUTO");
}
dtmfMethodBox.setSelectedItem(selString);
}
}

@ -26,7 +26,7 @@ public class SIPAccountRegistration
public static String DEFAULT_KEEP_ALIVE_INTERVAL = "25";
private String defaultDTMFMethod = "RFC4733 / SIP-INFO";
private String defaultDTMFMethod = "AUTO_DTMF";
private String id;

@ -7,6 +7,7 @@
package net.java.sip.communicator.service.neomedia;
import net.java.sip.communicator.service.neomedia.event.*;
import net.java.sip.communicator.service.protocol.*;
/**
* Extends the <tt>MediaStream</tt> interface and adds methods specific to
@ -52,23 +53,28 @@ public void setLocalUserAudioLevelListener(
/**
* Starts sending the specified <tt>DTMFTone</tt> until the
* <tt>stopSendingDTMF()</tt> method is called. Callers should keep in mind
* the fact that calling this method would most likely interrupt all audio
* transmission until the corresponding stop method is called. Also, calling
* this method successively without invoking the corresponding stop method
* between the calls, would simply replace the <tt>DTMFTone</tt> from the
* first call with that from the second.
* <tt>stopSendingDTMF()</tt> method is called (Excepts for INBAND DTMF,
* which stops by itself this is why where there is no need to call the
* stopSendingDTMF). Callers should keep in mind the fact that calling this
* method would most likely interrupt all audio transmission until the
* corresponding stop method is called. Also, calling this method
* successively without invoking the corresponding stop method between the
* calls will simply replace the <tt>DTMFTone</tt> from the first call with
* that from the second.
*
* @param tone the <tt>DTMFTone</tt> that we'd like to start sending.
* @param tone the <tt>DTMFTone</tt> to start sending.
* @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND).
*/
public void startSendingDTMF(DTMFTone tone);
public void startSendingDTMF(DTMFTone tone, DTMFEnum dtmfMethod);
/**
* Interrupts transmission of a <tt>DTMFTone</tt> started with the
* <tt>startSendingDTMF</tt> method. This method has no effect if no tone
* is being currently sent.
*
* @param tone the <tt>DTMFTone</tt> to start sending.
*/
public void stopSendingDTMF();
public void stopSendingDTMF(DTMFEnum dtmfMethod);
/**
* Registers a listener that would receive notification events if the
@ -85,11 +91,4 @@ public void setLocalUserAudioLevelListener(
* @param listener the listener that we'd like to unregister
*/
public void removeDTMFListener(DTMFListener listener);
/**
* Adds a new inband DTMF tone to send.
*
* @param tone the DTMF tone to send.
*/
public void addInbandDTMF(DTMFInbandTone tone);
}

@ -0,0 +1,25 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.neomedia;
/**
* Enumerates all available DTMF methods.
*
* @author Vincent Lucas
*/
public enum DTMFEnum
{
// Automatically selects RTP DTMF is telephon-event are available.
// Otherwise selects INBAND DMTF.
AUTO_DTMF,
// RTP DTMF as defined in RFC4733.
RTP_DTMF,
// SIP INFO DTMF.
SIP_INFO_DTMF,
// INBAND DTMF as defined in ITU recommendation Q.23.
INBAND_DTMF
}

@ -0,0 +1,220 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.neomedia;
import net.java.sip.communicator.service.protocol.*;
/**
* Represents all DTMF tones for RTP method (RFC4733).
*
* @author JM HEITZ
* @author Romain Philibert
* @author Emil Ivov
*/
public final class DTMFRtpTone
{
/**
* The "0" DTMF Tone
*/
public static final DTMFRtpTone DTMF_0=new DTMFRtpTone("0", (byte)0);
/**
* The "1" DTMF Tone
*/
public static final DTMFRtpTone DTMF_1=new DTMFRtpTone("1", (byte)1);
/**
* The "2" DTMF Tone
*/
public static final DTMFRtpTone DTMF_2=new DTMFRtpTone("2", (byte)2);
/**
* The "3" DTMF Tone
*/
public static final DTMFRtpTone DTMF_3=new DTMFRtpTone("3", (byte)3);
/**
* The "4" DTMF Tone
*/
public static final DTMFRtpTone DTMF_4=new DTMFRtpTone("4", (byte)4);
/**
* The "5" DTMF Tone
*/
public static final DTMFRtpTone DTMF_5=new DTMFRtpTone("5", (byte)5);
/**
* The "6" DTMF Tone
*/
public static final DTMFRtpTone DTMF_6=new DTMFRtpTone("6", (byte)6);
/**
* The "7" DTMF Tone
*/
public static final DTMFRtpTone DTMF_7=new DTMFRtpTone("7", (byte)7);
/**
* The "8" DTMF Tone
*/
public static final DTMFRtpTone DTMF_8=new DTMFRtpTone("8", (byte)8);
/**
* The "9" DTMF Tone
*/
public static final DTMFRtpTone DTMF_9=new DTMFRtpTone("9", (byte)9);
/**
* The "*" DTMF Tone
*/
public static final DTMFRtpTone DTMF_STAR=new DTMFRtpTone("*", (byte)10);
/**
* The "#" DTMF Tone
*/
public static final DTMFRtpTone DTMF_SHARP=new DTMFRtpTone("#", (byte)11);
/**
* The "A" DTMF Tone
*/
public static final DTMFRtpTone DTMF_A=new DTMFRtpTone("A", (byte)12);
/**
* The "B" DTMF Tone
*/
public static final DTMFRtpTone DTMF_B=new DTMFRtpTone("B", (byte)13);
/**
* The "C" DTMF Tone
*/
public static final DTMFRtpTone DTMF_C=new DTMFRtpTone("C", (byte)14);
/**
* The "D" DTMF Tone
*/
public static final DTMFRtpTone DTMF_D=new DTMFRtpTone("D", (byte)15);
/**
* The value of the DTMF tone
*/
private final String value;
/**
* The code of the tone, as specified by RFC 4733, and the we'll actually
* be sending over the wire.
*/
private final byte code;
/**
* Creates a DTMF instance with the specified tone value. The method is
* private since one would only have to use predefined static instances.
*
* @param value one of the DTMF_XXX fields, indicating the value of the tone.
* @param code the of the DTMF tone that we'll actually be sending over the
* wire, as specified by RFC 4733.
*/
private DTMFRtpTone(String value, byte code)
{
this.value = value;
this.code = code;
}
/**
* Returns the string representation of this DTMF tone.
*
* @return the <tt>String</tt> representation of this DTMF tone.
*/
public String getValue()
{
return this.value;
}
/**
* Indicates whether some other object is "equal to" this tone.
*
* @param target the reference object with which to compare.
*
* @return <tt>true</tt> if target represents the same tone as this
* object.
*/
public boolean equals(Object target)
{
if(!(target instanceof DTMFRtpTone))
{
return false;
}
DTMFRtpTone targetDTMFTone = (DTMFRtpTone)(target);
return targetDTMFTone.value.equals(this.value);
}
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hashtables such as those provided by
* <code>java.util.Hashtable</code>. The method would actually return the
* hashcode of the string representation of this DTMF tone.
*
* @return a hash code value for this object (same as calling
* getValue().hashCode()).
*/
public int hashCode()
{
return getValue().hashCode();
}
/**
* Returns the RFC 4733 code of this DTMF tone.
*
* @return the RFC 4733 code of this DTMF tone.
*/
public byte getCode()
{
return code;
}
/**
* Maps between protocol and media DTMF objects.
* @param tone The DTMFTone to be mapped to an DTMFRtpTone.
* @return The DTMFRtpTone corresponding to the tone specified.
*/
public static DTMFRtpTone mapTone(DTMFTone tone)
{
if(tone.equals(DTMFTone.DTMF_0))
return DTMFRtpTone.DTMF_0;
else if(tone.equals(DTMFTone.DTMF_1))
return DTMFRtpTone.DTMF_1;
else if(tone.equals(DTMFTone.DTMF_2))
return DTMFRtpTone.DTMF_2;
else if(tone.equals(DTMFTone.DTMF_3))
return DTMFRtpTone.DTMF_3;
else if(tone.equals(DTMFTone.DTMF_4))
return DTMFRtpTone.DTMF_4;
else if(tone.equals(DTMFTone.DTMF_5))
return DTMFRtpTone.DTMF_5;
else if(tone.equals(DTMFTone.DTMF_6))
return DTMFRtpTone.DTMF_6;
else if(tone.equals(DTMFTone.DTMF_7))
return DTMFRtpTone.DTMF_7;
else if(tone.equals(DTMFTone.DTMF_8))
return DTMFRtpTone.DTMF_8;
else if(tone.equals(DTMFTone.DTMF_9))
return DTMFRtpTone.DTMF_9;
else if(tone.equals(DTMFTone.DTMF_A))
return DTMFRtpTone.DTMF_A;
else if(tone.equals(DTMFTone.DTMF_B))
return DTMFRtpTone.DTMF_B;
else if(tone.equals(DTMFTone.DTMF_C))
return DTMFRtpTone.DTMF_C;
else if(tone.equals(DTMFTone.DTMF_D))
return DTMFRtpTone.DTMF_D;
else if(tone.equals(DTMFTone.DTMF_SHARP))
return DTMFRtpTone.DTMF_SHARP;
else if(tone.equals(DTMFTone.DTMF_STAR))
return DTMFRtpTone.DTMF_STAR;
return null;
}
}

@ -1,175 +0,0 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.neomedia;
/**
* Represents all DTMF tones.
*
* @author JM HEITZ
* @author Romain Philibert
* @author Emil Ivov
*/
public final class DTMFTone
{
/**
* The "0" DTMF Tone
*/
public static final DTMFTone DTMF_0=new DTMFTone("0", (byte)0);
/**
* The "1" DTMF Tone
*/
public static final DTMFTone DTMF_1=new DTMFTone("1", (byte)1);
/**
* The "2" DTMF Tone
*/
public static final DTMFTone DTMF_2=new DTMFTone("2", (byte)2);
/**
* The "3" DTMF Tone
*/
public static final DTMFTone DTMF_3=new DTMFTone("3", (byte)3);
/**
* The "4" DTMF Tone
*/
public static final DTMFTone DTMF_4=new DTMFTone("4", (byte)4);
/**
* The "5" DTMF Tone
*/
public static final DTMFTone DTMF_5=new DTMFTone("5", (byte)5);
/**
* The "6" DTMF Tone
*/
public static final DTMFTone DTMF_6=new DTMFTone("6", (byte)6);
/**
* The "7" DTMF Tone
*/
public static final DTMFTone DTMF_7=new DTMFTone("7", (byte)7);
/**
* The "8" DTMF Tone
*/
public static final DTMFTone DTMF_8=new DTMFTone("8", (byte)8);
/**
* The "9" DTMF Tone
*/
public static final DTMFTone DTMF_9=new DTMFTone("9", (byte)9);
/**
* The "*" DTMF Tone
*/
public static final DTMFTone DTMF_STAR=new DTMFTone("*", (byte)10);
/**
* The "#" DTMF Tone
*/
public static final DTMFTone DTMF_SHARP=new DTMFTone("#", (byte)11);
/**
* The "A" DTMF Tone
*/
public static final DTMFTone DTMF_A=new DTMFTone("A", (byte)12);
/**
* The "B" DTMF Tone
*/
public static final DTMFTone DTMF_B=new DTMFTone("B", (byte)13);
/**
* The "C" DTMF Tone
*/
public static final DTMFTone DTMF_C=new DTMFTone("C", (byte)14);
/**
* The "D" DTMF Tone
*/
public static final DTMFTone DTMF_D=new DTMFTone("D", (byte)15);
/**
* The value of the DTMF tone
*/
private final String value;
/**
* The code of the tone, as specified by RFC 4733, and the we'll actually
* be sending over the wire.
*/
private final byte code;
/**
* Creates a DTMF instance with the specified tone value. The method is
* private since one would only have to use predefined static instances.
*
* @param value one of the DTMF_XXX fields, indicating the value of the tone.
* @param code the of the DTMF tone that we'll actually be sending over the
* wire, as specified by RFC 4733.
*/
private DTMFTone(String value, byte code)
{
this.value = value;
this.code = code;
}
/**
* Returns the string representation of this DTMF tone.
*
* @return the <tt>String</tt> representation of this DTMF tone.
*/
public String getValue()
{
return this.value;
}
/**
* Indicates whether some other object is "equal to" this tone.
*
* @param target the reference object with which to compare.
*
* @return <tt>true</tt> if target represents the same tone as this
* object.
*/
public boolean equals(Object target)
{
if(!(target instanceof DTMFTone))
{
return false;
}
DTMFTone targetDTMFTone = (DTMFTone)(target);
return targetDTMFTone.value.equals(this.value);
}
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hashtables such as those provided by
* <code>java.util.Hashtable</code>. The method would actually return the
* hashcode of the string representation of this DTMF tone.
*
* @return a hash code value for this object (same as calling
* getValue().hashCode()).
*/
public int hashCode()
{
return getValue().hashCode();
}
/**
* Returns the RFC 4733 code of this DTMF tone.
*
* @return the RFC 4733 code of this DTMF tone.
*/
public byte getCode()
{
return code;
}
}

@ -12,7 +12,7 @@
/**
* This event represents starting or ending reception of a specific
* <tt>DTMFTone</tt>.
* <tt>DTMFRtpTone</tt>.
*
* @author Emil Ivov
*/
@ -27,7 +27,7 @@ public class DTMFToneEvent
/**
* The tone that this event is pertaining to.
*/
private final DTMFTone dtmfTone;
private final DTMFRtpTone dtmfTone;
/**
* Creates an instance of this <tt>DTMFToneEvent</tt> with the specified
@ -37,7 +37,7 @@ public class DTMFToneEvent
* tone.
* @param dtmfTone the tone that we (started/stopped) receiving.
*/
public DTMFToneEvent(AudioMediaStream source, DTMFTone dtmfTone)
public DTMFToneEvent(AudioMediaStream source, DTMFRtpTone dtmfTone)
{
super(source);
@ -49,7 +49,7 @@ public DTMFToneEvent(AudioMediaStream source, DTMFTone dtmfTone)
*
* @return the <tt>DTMFTone</tt> instance that this event pertains to.
*/
public DTMFTone getDtmfTone()
public DTMFRtpTone getDtmfTone()
{
return dtmfTone;
}

Loading…
Cancel
Save