📄 sipprovider.java
字号:
{ printLog("message passed to transaction: "+key,LogLevel.MEDIUM);
((SipProviderListener)listeners.get(key)).onReceivedMessage(this,msg);
return;
}
// try to look for a dialog
key=msg.getDialogId();
printLog("DEBUG: dialog-id: "+key,LogLevel.MEDIUM);
if (listeners.containsKey(key))
{ printLog("message passed to dialog: "+key,LogLevel.MEDIUM);
((SipProviderListener)listeners.get(key)).onReceivedMessage(this,msg);
return;
}
// try to look for a UAS
key=msg.getMethodId();
if (listeners.containsKey(key))
{ printLog("message passed to uas: "+key,LogLevel.MEDIUM);
((SipProviderListener)listeners.get(key)).onReceivedMessage(this,msg);
return;
}
// try to look for a default UA
if (listeners.containsKey(ANY))
{ printLog("message passed to uas: "+ANY,LogLevel.MEDIUM);
((SipProviderListener)listeners.get(ANY)).onReceivedMessage(this,msg);
return;
}
// if we are here, no listener_ID matched..
printLog("No SipListener found matching that message: message DISCARDED",LogLevel.HIGH);
//printLog("Pending SipProviderListeners= "+getListeners().size(),3);
printLog("Pending SipProviderListeners= "+listeners.size(),LogLevel.MEDIUM);
}
catch (Exception e)
{ printWarning("Error handling a new incoming message",LogLevel.HIGH);
printException(e,LogLevel.MEDIUM);
if (exception_listeners==null || exception_listeners.size()==0)
{ System.err.println("Error handling a new incoming message");
e.printStackTrace();
}
else
{ for (Iterator i=exception_listeners.iterator(); i.hasNext(); )
try
{ ((SipProviderExceptionListener)i.next()).onMessageException(msg,e);
}
catch (Exception e2)
{ printWarning("Error handling handling the Exception",LogLevel.HIGH);
printException(e2,LogLevel.MEDIUM);
}
}
}
}
/** Adds a new Connection */
private void addConnection(ConnectedTransport conn)
{ ConnectionIdentifier conn_id=new ConnectionIdentifier(conn);
if (connections.containsKey(conn_id))
{ // remove the previous connection
printLog("trying to add the already established connection "+conn_id,LogLevel.HIGH);
printLog("connection "+conn_id+" will be replaced",LogLevel.HIGH);
ConnectedTransport old_conn=(ConnectedTransport)connections.get(conn_id);
old_conn.halt();
connections.remove(conn_id);
}
else
if (connections.size()>=nmax_connections)
{ // remove the older unused connection
printLog("reached the maximum number of connection: removing the older unused connection",LogLevel.HIGH);
long older_time=System.currentTimeMillis();
ConnectionIdentifier older_id=null;
for (Enumeration e=connections.elements(); e.hasMoreElements(); )
{ ConnectedTransport co=(ConnectedTransport)e.nextElement();
if (co.getLastTimeMillis()<older_time) older_id=new ConnectionIdentifier(co);
}
if (older_id!=null) removeConnection(older_id);
}
connections.put(conn_id,conn);
conn_id=new ConnectionIdentifier(conn);
conn=(ConnectedTransport)connections.get(conn_id);
// DEBUG log:
printLog("active connenctions:",LogLevel.LOW);
for (Enumeration e=connections.keys(); e.hasMoreElements(); )
{ ConnectionIdentifier id=(ConnectionIdentifier)e.nextElement();
printLog("conn-id="+id+": "+((ConnectedTransport)connections.get(id)).toString(),LogLevel.LOW);
}
}
/** Removes a Connection */
private void removeConnection(ConnectionIdentifier conn_id)
{ if (connections.containsKey(conn_id))
{ ConnectedTransport conn=(ConnectedTransport)connections.get(conn_id);
conn.halt();
connections.remove(conn_id);
// DEBUG log:
printLog("active connenctions:",LogLevel.LOW);
for (Enumeration e=connections.elements(); e.hasMoreElements(); )
{ ConnectedTransport co=(ConnectedTransport)e.nextElement();
printLog("conn "+co.toString(),LogLevel.LOW);
}
}
}
//************************* Callback methods *************************
/** When a new SIP message is received. */
public void onReceivedMessage(Transport transport, Message msg)
{ processReceivedMessage(msg);
}
/** When Transport terminates. */
public void onTransportTerminated(Transport transport, Exception error)
{ printLog("transport "+transport+" terminated",LogLevel.MEDIUM);
if (transport.getProtocol().equals(PROTO_TCP))
{ ConnectionIdentifier conn_id=new ConnectionIdentifier((ConnectedTransport)transport);
removeConnection(conn_id);
}
if (error!=null)
printException(error,LogLevel.HIGH);
}
/** When a new incoming Connection is established */
public void onIncomingConnection(TcpServer tcp_server, TcpSocket socket)
{ printLog("incoming connection from "+socket.getAddress()+":"+socket.getPort(),LogLevel.MEDIUM);
ConnectedTransport conn=new TcpTransport(socket,this);
printLog("tcp connection "+conn+" opened",LogLevel.MEDIUM);
addConnection(conn);
}
/** When TcpServer terminates. */
public void onServerTerminated(TcpServer tcp_server, Exception error)
{ printLog("tcp server "+tcp_server+" terminated",LogLevel.MEDIUM);
}
//************************** Other methods ***************************
/** Picks a fresh branch value.
* The branch ID MUST be unique across space and time for
* all requests sent by the UA.
* The branch ID always begin with the characters "z9hG4bK". These
* 7 characters are used by RFC 3261 as a magic cookie. */
public static String pickBranch()
{ //String str=Long.toString(Math.abs(Random.nextLong()),16);
//if (str.length()<5) str+="00000";
//return "z9hG4bK"+str.substring(0,5);
return "z9hG4bK"+Random.nextNumString(5);
}
/** Picks an unique branch value based on a SIP message.
* This value could also be used as transaction ID */
public String pickBranch(Message msg)
{ StringBuffer sb=new StringBuffer();
sb.append(msg.getRequestLine().getAddress().toString());
sb.append(getViaAddress()+getPort());
ViaHeader top_via=msg.getViaHeader();
if (top_via.hasBranch())
sb.append(top_via.getBranch());
else
{ sb.append(top_via.getHost()+top_via.getPort());
sb.append(msg.getCSeqHeader().getSequenceNumber());
sb.append(msg.getCallIdHeader().getCallId());
sb.append(msg.getFromHeader().getTag());
sb.append(msg.getToHeader().getTag());
}
//return "z9hG4bK"+(new MD5(unique_str)).asHex().substring(0,9);
return "z9hG4bK"+(new SimpleDigest(5,sb.toString())).asHex();
}
/** Picks a new tag.
* A tag MUST be globally unique and cryptographically random
* with at least 32 bits of randomness. A property of this selection
* requirement is that a UA will place a different tag into the From
* header of an INVITE than it would place into the To header of the
* response to the same INVITE. This is needed in order for a UA to
* invite itself to a session. */
public static String pickTag()
{ //String str=Long.toString(Math.abs(Random.nextLong()),16);
//if (str.length()<8) str+="00000000";
//return str.substring(0,8);
return "z9hG4bK"+Random.nextNumString(8);
}
/** Picks a new tag. The tag is generated uniquely based on message <i>req</i>.
* This tag can be generated for responses in a stateless
* manner - in a manner that will generate the same tag for the
* same request consistently.
*/
public static String pickTag(Message req)
{ //return String.valueOf(tag_generator++);
//return (new MD5(request.toString())).asHex().substring(0,8);
return (new SimpleDigest(8,req.toString())).asHex();
}
/** Picks a new call-id.
* The call-id is a globally unique
* identifier over space and time. It is implemented in the
* form "localid@host". Call-id must be considered case-sensitive and is
* compared byte-by-byte. */
public String pickCallId()
{ //String str=Long.toString(Math.abs(Random.nextLong()),16);
//if (str.length()<12) str+="000000000000";
//return str.substring(0,12)+"@"+getViaAddress();
return Random.nextNumString(12)+"@"+getViaAddress();
}
/** picks an initial CSeq */
public static int pickInitialCSeq()
{ return 1;
}
/** (<b>Deprecated</b>) Constructs a NameAddress based on an input string.
* The input string can be a:
* <br> - <i>user</i> name,
* <br> - <i>user@address</i> url,
* <br> - <i>"Name" <sip:user@address></i> address,
* <p>
* In the former case,
* a SIP URL is costructed using the outbound proxy as host address if present,
* otherwise the local via address is used. */
public NameAddress completeNameAddress(String str)
{ if (str.indexOf("<sip:")>=0) return new NameAddress(str);
else
{ SipURL url=completeSipURL(str);
return new NameAddress(url);
}
}
/** Constructs a SipURL based on an input string. */
private SipURL completeSipURL(String str)
{ // in case it is passed only the 'user' field, add '@'<outbound_proxy>[':'<outbound_port>]
if (!str.startsWith("sip:") && str.indexOf("@")<0 && str.indexOf(".")<0 && str.indexOf(":")<0)
{ // may be it is just the user name..
String url="sip:"+str+"@";
if (outbound_proxy!=null)
{ url+=outbound_proxy.getAddress().toString();
int port=outbound_proxy.getPort();
if (port>0 && port!=SipStack.default_port) url+=":"+port;
}
else
{ url+=via_addr;
if (host_port>0 && host_port!=SipStack.default_port) url+=":"+host_port;
}
return new SipURL(url);
}
else return new SipURL(str);
}
/** Constructs a SipURL for the given <i>username</i> on the local SIP UA.
* If <i>username</i> is null, only host address and port are used. */
/*public SipURL getSipURL(String user_name)
{ return new SipURL(user_name,via_addr,(host_port!=SipStack.default_port)?host_port:-1);
}*/
//******************************* Logs *******************************
/** Gets a String value for this object */
public String toString()
{ if (host_ipaddr==null) return host_port+"/"+transportProtocolsToString();
else return host_ipaddr.toString()+":"+host_port+"/"+transportProtocolsToString();
}
/** Adds a new string to the default Log */
private final void printLog(String str, int level)
{ if (event_log!=null)
{ String provider_id=(host_ipaddr==null)? Integer.toString(host_port) : host_ipaddr.toString()+":"+host_port;
event_log.println("SipProvider-"+provider_id+": "+str,level+SipStack.LOG_LEVEL_TRANSPORT);
}
}
/** Adds a WARNING to the default Log */
private final void printWarning(String str, int level)
{ printLog("WARNING: "+str,level);
}
/** Adds the Exception message to the default Log */
private final void printException(Exception e, int level)
{ if (event_log!=null) event_log.printException(e,level+SipStack.LOG_LEVEL_TRANSPORT);
}
/** Adds the SIP message to the messageslog */
private final void printMessageLog(String proto, String addr, int port, int len, Message msg, String str)
{ if (log_all_packets || len>=MIN_MESSAGE_LENGTH)
{ if (message_log!=null)
{ message_log.printPacketTimestamp(proto,addr,port,len,str+"\r\n"+msg.toString()+"-----End-of-message-----\r\n",1);
}
if (event_log!=null)
{ String first_line=msg.getFirstLine();
if (first_line!=null) first_line=first_line.trim(); else first_line="NOT a SIP message";
event_log.print("\r\n");
event_log.printPacketTimestamp(proto,addr,port,len,first_line+", "+str,1);
event_log.print("\r\n");
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -