📄 sipmanager.java
字号:
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.openfire.sip.tester.stack;
import org.jivesoftware.openfire.sip.tester.comm.CommunicationsException;
import org.jivesoftware.openfire.sip.tester.comm.CommunicationsListener;
import org.jivesoftware.openfire.sip.tester.Log;
import org.jivesoftware.openfire.sip.tester.security.UserCredentials;
import org.jivesoftware.openfire.sip.tester.security.SipSecurityManager;
import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TooManyListenersException;
/**
* Title: SIP Register Tester
*
* @author Thiago Rocha Camargo (thiago@jivesoftware.com)
*/
public class SipManager implements SipListener {
protected static final int RETRY_OBJECT_DELETES = 10;
protected static final long RETRY_OBJECT_DELETES_AFTER = 500;
protected static final String DEFAULT_TRANSPORT = "udp";
protected InetAddress localAddress = null;
public SipFactory sipFactory;
public AddressFactory addressFactory;
public HeaderFactory headerFactory;
public MessageFactory messageFactory;
SipStack sipStack;
public boolean isBusy = true;
ListeningPoint listeningPoint;
public SipProvider sipProvider;
private InetSocketAddress publicIpAddress = null;
protected String sipStackPath = "gov.nist";
protected String currentlyUsedURI = null;
protected String displayName = null;
protected String transport = null;
protected String registrarAddress = null;
protected int localPort = -1;
protected int registrarPort = -1;
protected int registrationsExpiration = -1;
protected String registrarTransport = null;
private int registerRetries = 0;
protected String stackAddress = null;
protected String stackName = "JiveSIP";
protected FromHeader fromHeader = null;
protected ContactHeader contactHeader = null;
protected ArrayList<ViaHeader> viaHeaders = null;
protected static final int MAX_FORWARDS = 70;
protected MaxForwardsHeader maxForwardsHeader = null;
protected long registrationTransaction = -1;
protected ArrayList<CommunicationsListener> listeners = new ArrayList<CommunicationsListener>();
protected boolean isStarted = false;
private RegisterProcessing registerProcessing = null;
public SipSecurityManager sipSecurityManager = null;
/**
* Constructor. It only creates a SipManager instance without initializing
* the stack itself.
*
* @param localAddress localAddress
*/
public SipManager(InetAddress localAddress) {
this.localAddress = localAddress;
registerProcessing = new RegisterProcessing(this);
sipSecurityManager = new SipSecurityManager();
registerRetries = 0;
}
/**
* Creates and initializes JAIN SIP objects (factories, stack, listening
* point and provider). Once this method is called the application is ready
* to handle (incoming and outgoing) sip messages.
*
* @throws CommunicationsException if an axception should occur during the initialization
* process
*/
public void start() throws CommunicationsException {
initProperties();
SIPConfig.setSystemProperties();
this.sipFactory = SipFactory.getInstance();
sipFactory.setPathName(sipStackPath);
try {
addressFactory = sipFactory.createAddressFactory();
headerFactory = sipFactory.createHeaderFactory();
messageFactory = sipFactory.createMessageFactory();
}
catch (PeerUnavailableException ex) {
Log.error("start", ex);
throw new CommunicationsException(
"Could not create factories!", ex);
}
try {
sipStack = sipFactory.createSipStack(System.getProperties());
((SipCommRouter) sipStack.getRouter())
.setOutboundProxy(SIPConfig.getOutboundProxy());
}
catch (PeerUnavailableException ex) {
Log.error("start", ex);
throw new CommunicationsException(
"Imposs�vel conectar!\n"
+ "O proxy pode n�o est� acess�vel.\nVerifique sua conex�o."
+ "(Syntax:<proxy_address:port/transport>)", ex);
}
try {
boolean successfullyBound = false;
while (!successfullyBound) {
try {
publicIpAddress = new InetSocketAddress(localAddress, localPort);
listeningPoint = sipStack.createListeningPoint(
localPort, transport);
}
catch (InvalidArgumentException ex) {
// choose another port between 1024 and 65000
localPort = (int) ((65000 - 1024) * Math.random()) + 1024;
try {
Thread.sleep(1000);
}
catch (Exception e) {
// Do Nothing
}
continue;
}
successfullyBound = true;
}
}
catch (TransportNotSupportedException ex) {
throw new CommunicationsException(
"Transport "
+ transport
+ " is not suppported by the stack!\n Try specifying another"
+ " transport in Mais property files.\n", ex);
}
try {
sipProvider = sipStack.createSipProvider(listeningPoint);
}
catch (ObjectInUseException ex) {
Log.error("start", ex);
throw new CommunicationsException(
"Could not create factories!\n", ex);
}
try {
sipProvider.addSipListener(this);
}
catch (TooManyListenersException exc) {
throw new CommunicationsException(
"Could not register SipManager as a sip listener!", exc);
}
sipSecurityManager.setHeaderFactory(headerFactory);
sipSecurityManager.setTransactionCreator(sipProvider);
sipSecurityManager.setSipManCallback(this);
// Make sure prebuilt headers are nulled so that they get reinited
// if this is a restart
contactHeader = null;
fromHeader = null;
viaHeaders = null;
maxForwardsHeader = null;
isStarted = true;
}
/**
* Unregisters listening points, deletes sip providers, and generally
* prepares the stack for a re-start(). This method is meant to be used when
* properties are changed and should be reread by the stack.
*
* @throws CommunicationsException CommunicationsException
*/
synchronized public void stop() throws CommunicationsException {
if (sipStack == null)
return;
// Delete SipProvider
int tries;
for (tries = 0; tries < SipManager.RETRY_OBJECT_DELETES; tries++) {
try {
sipStack.deleteSipProvider(sipProvider);
}
catch (ObjectInUseException ex) {
SipManager.sleep(SipManager.RETRY_OBJECT_DELETES_AFTER);
continue;
}
break;
}
if (sipStack == null)
return;
if (tries >= SipManager.RETRY_OBJECT_DELETES)
throw new CommunicationsException(
"Failed to delete the sipProvider!");
if (sipStack == null)
return;
// Delete RI ListeningPoint
for (tries = 0; tries < SipManager.RETRY_OBJECT_DELETES; tries++) {
try {
sipStack.deleteListeningPoint(listeningPoint);
}
catch (ObjectInUseException ex) {
// Log.debug("Retrying delete of riListeningPoint!");
SipManager.sleep(SipManager.RETRY_OBJECT_DELETES_AFTER);
continue;
}
break;
}
if (sipStack != null) {
for (Iterator it = sipStack.getSipProviders(); it.hasNext();) {
SipProvider element = (SipProvider) it.next();
try {
sipStack.deleteSipProvider(element);
}
catch (Exception e) {
// Do nothing
}
}
}
if (tries >= SipManager.RETRY_OBJECT_DELETES)
throw new CommunicationsException(
"Failed to delete a listeningPoint!");
listeningPoint = null;
addressFactory = null;
messageFactory = null;
headerFactory = null;
sipStack = null;
registrarAddress = null;
viaHeaders = null;
contactHeader = null;
fromHeader = null;
}
/**
* Waits during _no_less_ than sleepFor milliseconds. Had to implement it on
* top of Thread.sleep() to guarantee minimum sleep time.
*
* @param sleepFor the number of miliseconds to wait
*/
protected static void sleep(long sleepFor) {
long startTime = System.currentTimeMillis();
long haveBeenSleeping = 0;
while (haveBeenSleeping < sleepFor) {
try {
Thread.sleep(sleepFor - haveBeenSleeping);
}
catch (InterruptedException ex) {
// we-ll have to wait again!
}
haveBeenSleeping = (System.currentTimeMillis() - startTime);
}
}
/**
* @param uri the currentlyUsedURI to set.
*/
public void setCurrentlyUsedURI(String uri) {
this.currentlyUsedURI = uri;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -