📄 sipprovider.java
字号:
/*
* Copyright (C) 2005 Luca Veltri - University of Parma - Italy
*
* This file is part of MjSip (http://www.mjsip.org)
*
* MjSip 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 2 of the License, or
* (at your option) any later version.
*
* MjSip 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 MjSip; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author(s):
* Luca Veltri (luca.veltri@unipr.it)
*/
package org.zoolu.sip.provider;
import org.zoolu.net.*;
import org.zoolu.sip.header.*;
import org.zoolu.sip.message.Message;
import org.zoolu.sip.address.*;
import org.zoolu.sip.transaction.Transaction;
import org.zoolu.tools.Configure;
import org.zoolu.tools.Configurable;
import org.zoolu.tools.Parser;
import org.zoolu.tools.Random;
import org.zoolu.tools.Log;
import org.zoolu.tools.LogLevel;
import org.zoolu.tools.RotatingLog;
//import org.zoolu.tools.MD5;
import org.zoolu.tools.SimpleDigest;
import org.zoolu.tools.DateFormat;
import java.util.Hashtable;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
//PersonalJava
//import java.util.HashSet;
//import java.util.Iterator;
import org.zoolu.tools.HashSet;
import org.zoolu.tools.Iterator;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Date;
/** SipProvider implements the SIP transport layer, that is the layer responsable for
* sending and receiving SIP messages. Messages are received by the callback function
* defined in the interface SipProviderListener.
* <p>
* SipProvider implements also multiplexing/demultiplexing service through the use of
* SIP interface identifiers and <i>onReceivedMessage()<i/> callback function
* of specific SipProviderListener.
* <p>
* A SipProviderListener can be added to a SipProvider through the
* addSipProviderListener(id,listener) method, where:
* <b> - <i>id<i/> is the SIP interface identifier the listener has to be bound to,
* <b> - <i>listener<i/> is the SipProviderListener that received messages are passed to.
* <p/>
* The SIP interface identifier specifies the type of messages the listener is going to
* receive for. Together with the specific SipProvider, it represents the complete SIP
* Service Access Point (SAP) address/identifier used for demultiplexing SIP messages
* at receiving side.
* <p/>
* The identifier can be of one of the three following types: transaction_id, dialog_id,
* or method_id. These types of identifiers characterize respectively:
* <br> - messages within a specific transaction,
* <br> - messages within a specific dialog,
* <br> - messages related to a specific SIP method.
* It is also possible to use the the identifier ANY to specify
* <br> - all messages that are out of any transactions, dialogs, or already specified
* method types.
* <p>
* When receiving a message, the SipProvider first tries to look for a matching
* transaction, then looks for a matching dialog, then for a matching method type,
* and finally for a default listener (i.e. that with identifier ANY).
* For the matched SipProviderListener, the method <i>onReceivedMessage()</i> is fired.
* <p>
* Note: no 482 (Loop Detected) responses are generated for requests that does not
* properly match any ongoing transactions, dialogs, nor method types.
*/
public class SipProvider implements Configurable, TransportListener, TcpServerListener
{
// **************************** Constants ****************************
/** UDP protocol type */
public static final String PROTO_UDP="udp";
/** TCP protocol type */
public static final String PROTO_TCP="tcp";
/** TLS protocol type */
public static final String PROTO_TLS="tls";
/** SCTP protocol type */
public static final String PROTO_SCTP="sctp";
/** String value "auto-configuration" used for auto configuration of the host address. */
public static final String AUTO_CONFIGURATION="AUTO-CONFIGURATION";
/** String value "auto-configuration" used for auto configuration of the host address. */
public static final String ALL_INTERFACES="ALL-INTERFACES";
/** String value "NO-OUTBOUND" used for setting no outbound proxy. */
//public static final String NO_OUTBOUND="NO-OUTBOUND";
/** Identifier used as listener id for capturing ANY incoming messages
* that does not match any active method_id, transaction_id, nor dialog_id.
* <br> In this context, "active" means that there is a active listener
* for that specific method, transaction, or dialog. */
public static final Identifier ANY=new Identifier("ANY");
/** Identifier used as listener id for capturing any incoming messages in PROMISQUE mode,
* that means that messages are passed to the present listener regardless of
* any other active SipProviderListeners for specific messages.
* <p/>
* More than one SipProviderListener can be added and be active concurrently
* for capturing messages in PROMISQUE mode. */
public static final Identifier PROMISQUE=new Identifier("PROMISQUE");
/** Minimum length for a valid SIP message. */
private static final int MIN_MESSAGE_LENGTH=12;
// ***************** Readable/configurable attributes *****************
/** Via address/name.
* Use 'auto-configuration' for auto detection, or let it undefined. */
String via_addr=null;
/** Local SIP port */
int host_port=0;
/** Network interface (IP address) used by SIP.
* Use 'ALL-INTERFACES' for binding SIP to all interfaces (or let it undefined). */
String host_ifaddr=null;
/** Transport protocols (the first protocol is used as default) */
String[] transport_protocols=null;
/** Max number of (contemporary) open connections */
int nmax_connections=0;
/** Outbound proxy (host_addr[:host_port]).
* Use 'NONE' for not using an outbound proxy (or let it undefined). */
SocketAddress outbound_proxy=null;
/** Whether logging all packets (including non-SIP keepalive tokens). */
boolean log_all_packets=false;
// for backward compatibility:
/** Outbound proxy addr (for backward compatibility). */
private String outbound_addr=null;
/** Outbound proxy port (for backward compatibility). */
private int outbound_port=-1;
// ********************* Non-readable attributes *********************
/** Event Loger */
protected Log event_log=null;
/** Message Loger */
protected Log message_log=null;
/** Network interface (IP address) used by SIP. */
IpAddress host_ipaddr=null;
/** Default transport */
String default_transport=null;
/** Whether using UDP as transport protocol */
boolean transport_udp=false;
/** Whether using TCP as transport protocol */
boolean transport_tcp=false;
/** Whether using TLS as transport protocol */
boolean transport_tls=false;
/** Whether using SCTP as transport protocol */
boolean transport_sctp=false;
/** Whether adding 'rport' parameter on outgoing requests. */
boolean rport=true;
/** Whether forcing 'rport' parameter on incoming requests ('force-rport' mode). */
boolean force_rport=false;
/** List of provider listeners */
Hashtable listeners=null;
/** List of exception listeners */
HashSet exception_listeners=null;
/** UDP transport */
UdpTransport udp=null;
/** Tcp server */
TcpServer tcp_server=null;
/** Connections */
Hashtable connections=null;
// *************************** Costructors ***************************
/** Creates a void SipProvider. */
/*protected SipProvider()
{
}*/
/** Creates a new SipProvider. */
public SipProvider(String via_addr, int port)
{ init(via_addr,port,null,null);
initlog();
startTrasport();
}
/** Creates a new SipProvider.
* Costructs the SipProvider, initializing the SipProviderListeners, the transport protocols, and other attributes. */
public SipProvider(String via_addr, int port, String[] protocols, String ifaddr)
{ init(via_addr,port,protocols,ifaddr);
initlog();
startTrasport();
}
/** Creates a new SipProvider.
* The SipProvider attributres are read from file. */
public SipProvider(String file)
{ if (!SipStack.isInit()) SipStack.init(file);
new Configure(this,file);
init(via_addr,host_port,transport_protocols,host_ifaddr);
initlog();
startTrasport();
}
/** Inits the SipProvider, initializing the SipProviderListeners, the transport protocols, the outbound proxy, and other attributes. */
private void init(String viaddr, int port, String[] protocols, String ifaddr)
{ if (!SipStack.isInit()) SipStack.init();
via_addr=viaddr;
if (via_addr==null || via_addr.equalsIgnoreCase(AUTO_CONFIGURATION)) via_addr=IpAddress.getLocalHostAddress().toString();
host_port=port;
if (host_port<=0) host_port=SipStack.default_port;
host_ipaddr=null;
if (ifaddr!=null && !ifaddr.equalsIgnoreCase(ALL_INTERFACES))
{ try { host_ipaddr=IpAddress.getByName(ifaddr); } catch (IOException e) { e.printStackTrace(); host_ipaddr=null; }
}
transport_protocols=protocols;
if (transport_protocols==null) transport_protocols=SipStack.default_transport_protocols;
default_transport=transport_protocols[0];
for (int i=0; i<transport_protocols.length; i++)
{ transport_protocols[i]=transport_protocols[i].toLowerCase();
if (transport_protocols[i].equals(PROTO_UDP)) transport_udp=true;
else
if (transport_protocols[i].equals(PROTO_TCP)) transport_tcp=true;
/*
else
if (transport_protocols[i].equals(PROTO_TLS)) transport_tls=true;
else
if (transport_protocols[i].equals(PROTO_SCTP)) transport_sctp=true;
*/
}
if (nmax_connections<=0) nmax_connections=SipStack.default_nmax_connections;
// just for backward compatibility..
if (outbound_port<0) outbound_port=SipStack.default_port;
if (outbound_addr!=null)
{ if (outbound_addr.equalsIgnoreCase(Configure.NONE) || outbound_addr.equalsIgnoreCase("NO-OUTBOUND")) outbound_proxy=null;
else outbound_proxy=new SocketAddress(outbound_addr,outbound_port);
}
rport=SipStack.use_rport;
force_rport=SipStack.force_rport;
exception_listeners=new HashSet();
listeners=new Hashtable();
connections=new Hashtable();
}
/** Inits logs. */
private void initlog()
{ if (SipStack.debug_level>0)
{ String filename=SipStack.log_path+"//"+via_addr+"."+host_port;
event_log=new RotatingLog(filename+"_events.log",null,SipStack.debug_level,SipStack.max_logsize*1024,SipStack.log_rotations,SipStack.rotation_scale,SipStack.rotation_time);
message_log=new RotatingLog(filename+"_messages.log",null,SipStack.debug_level,SipStack.max_logsize*1024,SipStack.log_rotations,SipStack.rotation_scale,SipStack.rotation_time);
}
printLog("Date: "+DateFormat.formatHHMMSS(new Date()),LogLevel.HIGH);
printLog("SipStack: "+SipStack.release,LogLevel.HIGH);
printLog("new SipProvider(): "+toString(),LogLevel.HIGH);
}
/** Starts the transport services. */
private void startTrasport()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -