📄 sipprovider.java
字号:
{ printLog("adding SipProviderExceptionListener",LogLevel.MEDIUM);
if (exception_listeners.contains(e_listener))
{ printWarning("trying to add an already present SipProviderExceptionListener.",LogLevel.HIGH);
return false;
}
else
{ exception_listeners.add(e_listener);
return true;
}
}
/** Removes a SipProviderExceptionListener.
* @param e_listener is the SipProviderExceptionListener.
* @return It returns <i>true</i> if the SipProviderExceptionListener has been correctly removed,
* <i>false</i> if the SipProviderExceptionListener is missed. */
public boolean removeSipProviderExceptionListener(SipProviderExceptionListener e_listener)
{ printLog("removing SipProviderExceptionListener",LogLevel.MEDIUM);
if (!exception_listeners.contains(e_listener))
{ printWarning("trying to remove a missed SipProviderExceptionListener.",LogLevel.HIGH);
return false;
}
else
{ exception_listeners.remove(e_listener);
return true;
}
}
/** Sends a Message, specifing the transport portocol, nexthop address and port.
* <p> This is a low level method and
* forces the message to be routed to a specific nexthop address, port and transport,
* regardless whatever the Via, Route, or request-uri, address to.
* <p>
* In case of connection-oriented transport, the connection is selected as follows:
* <br> - if an existing connection is found matching the destination
* end point (socket), such connection is used, otherwise
* <br> - a new connection is established
*
* @return It returns a Connection in case of connection-oriented delivery
* (e.g. TCP) or null in case of connection-less delivery (e.g. UDP)
*/
public ConnectionIdentifier sendMessage(Message msg, String proto, String dest_addr, int dest_port, int ttl)
{ if (log_all_packets || msg.getLength()>MIN_MESSAGE_LENGTH) printLog("Resolving host address '"+dest_addr+"'",LogLevel.MEDIUM);
try
{ IpAddress dest_ipaddr=IpAddress.getByName(dest_addr);
return sendMessage(msg,proto,dest_ipaddr,dest_port,ttl);
}
catch (Exception e)
{ printException(e,LogLevel.HIGH);
return null;
}
}
/** Sends a Message, specifing the transport portocol, nexthop address and port. */
private ConnectionIdentifier sendMessage(Message msg, String proto, IpAddress dest_ipaddr, int dest_port, int ttl)
{ ConnectionIdentifier conn_id=new ConnectionIdentifier(proto,dest_ipaddr,dest_port);
if (log_all_packets || msg.getLength()>MIN_MESSAGE_LENGTH) printLog("Sending message to "+conn_id,LogLevel.MEDIUM);
if (transport_udp && proto.equals(PROTO_UDP))
{ // UDP
//printLog("using UDP",LogLevel.LOW);
conn_id=null;
try
{ // if (ttl>0 && multicast_address) do something?
udp.sendMessage(msg,dest_ipaddr,dest_port);
}
catch (IOException e)
{ printException(e,LogLevel.HIGH);
return null;
}
}
else
if (transport_tcp && proto.equals(PROTO_TCP))
{ // TCP
//printLog("using TCP",LogLevel.LOW);
if (!connections.containsKey(conn_id))
{ printLog("no active connection found matching "+conn_id,LogLevel.MEDIUM);
printLog("open "+proto+" connection to "+dest_ipaddr+":"+dest_port,LogLevel.MEDIUM);
TcpTransport conn=null;
try
{ conn=new TcpTransport(dest_ipaddr,dest_port,this);
}
catch (Exception e)
{ printLog("connection setup FAILED",LogLevel.HIGH);
return null;
}
printLog("connection "+conn+" opened",LogLevel.HIGH);
addConnection(conn);
}
else
{ printLog("active connection found matching "+conn_id,LogLevel.MEDIUM);
}
ConnectedTransport conn=(ConnectedTransport)connections.get(conn_id);
if (conn!=null)
{ printLog("sending data through conn "+conn,LogLevel.MEDIUM);
try
{ conn.sendMessage(msg);
conn_id=new ConnectionIdentifier(conn);
}
catch (IOException e)
{ printException(e,LogLevel.HIGH);
return null;
}
}
else
{ // this point has not to be reached
printLog("ERROR: conn "+conn_id+" not found: abort.",LogLevel.MEDIUM);
return null;
}
}
else
{ // otherwise
printWarning("Unsupported protocol ("+proto+"): Message discarded",LogLevel.HIGH);
return null;
}
// logs
String dest_addr=dest_ipaddr.toString();
printMessageLog(proto,dest_addr,dest_port,msg.getLength(),msg,"sent");
return conn_id;
}
/** Sends the message <i>msg</i>.
* <p>
* The destination for the request is computed as follows:
* <br> - if <i>outbound_addr</i> is set, <i>outbound_addr</i> and
* <i>outbound_port</i> are used, otherwise
* <br> - if message has Route header with lr option parameter (i.e. RFC3261 compliant),
* the first Route address is used, otherwise
* <br> - the request's Request-URI is considered.
* <p>
* The destination for the response is computed based on the sent-by parameter in
* the Via header field (RFC3261 compliant)
* <p>
* As transport it is used the protocol specified in the 'via' header field
* <p>
* In case of connection-oriented transport:
* <br> - if an already established connection is found matching the destination
* end point (socket), such connection is used, otherwise
* <br> - a new connection is established
*
* @return Returns a ConnectionIdentifier in case of connection-oriented delivery
* (e.g. TCP) or null in case of connection-less delivery (e.g. UDP)
*/
public ConnectionIdentifier sendMessage(Message msg)
{ printLog("Sending message:\r\n"+msg.toString(),LogLevel.LOWER);
// select the transport protocol
ViaHeader via=msg.getViaHeader();
String proto=via.getProtocol().toLowerCase();
printLog("using transport "+proto,LogLevel.MEDIUM);
// select the destination address and port
String dest_addr=null;
int dest_port=0;
int ttl=0;
if (msg.isRequest())
{ // REQUESTS
if (outbound_proxy!=null)
{ dest_addr=outbound_proxy.getAddress().toString();
dest_port=outbound_proxy.getPort();
}
else
{ if (msg.hasRouteHeader() && msg.getRouteHeader().getNameAddress().getAddress().hasLr())
{
SipURL url=msg.getRouteHeader().getNameAddress().getAddress();
dest_addr=url.getHost();
dest_port=url.getPort();
}
else
{ SipURL url=msg.getRequestLine().getAddress();
dest_addr=url.getHost();
dest_port=url.getPort();
if (url.hasMaddr())
{ dest_addr=url.getMaddr();
if (url.hasTtl()) ttl=url.getTtl();
// update the via header by adding maddr and ttl params
via.setMaddr(dest_addr);
if (ttl>0) via.setTtl(ttl);
msg.removeViaHeader();
msg.addViaHeader(via);
}
}
}
}
else
{ // RESPONSES
SipURL url=via.getSipURL();
if (via.hasReceived()) dest_addr=via.getReceived(); else dest_addr=url.getHost();
if (via.hasRport()) dest_port=via.getRport();
if (dest_port<=0) dest_port=url.getPort();
}
if (dest_port<=0) dest_port=SipStack.default_port;
return sendMessage(msg,proto,dest_addr,dest_port,ttl);
}
/** Sends the message <i>msg</i> using the specified connection. */
public ConnectionIdentifier sendMessage(Message msg, ConnectionIdentifier conn_id)
{ if (log_all_packets || msg.getLength()>MIN_MESSAGE_LENGTH) printLog("Sending message through conn "+conn_id,LogLevel.HIGH);
printLog("message:\r\n"+msg.toString(),LogLevel.LOWER);
if (conn_id!=null && connections.containsKey(conn_id))
{ // connection exists
printLog("active connection found matching "+conn_id,LogLevel.MEDIUM);
ConnectedTransport conn=(ConnectedTransport)connections.get(conn_id);
try
{ conn.sendMessage(msg);
// logs
//String proto=conn.getProtocol();
String proto=conn.getProtocol();
String dest_addr=conn.getRemoteAddress().toString();
int dest_port=conn.getRemotePort();
printMessageLog(proto,dest_addr,dest_port,msg.getLength(),msg,"sent");
return conn_id;
}
catch (Exception e)
{ printException(e,LogLevel.HIGH);
}
}
//else
printLog("no active connection found matching "+conn_id,LogLevel.MEDIUM);
return sendMessage(msg);
}
/** Processes the message received.
* It is called each time a new message is received by the transport layer, and
* it performs the actual message processing. */
protected void processReceivedMessage(Message msg)
{ try
{ // logs
printMessageLog(msg.getTransportProtocol(),msg.getRemoteAddress(),msg.getRemotePort(),msg.getLength(),msg,"received");
// discard too short messages
if (msg.getLength()<=2)
{ if (log_all_packets) printLog("message too short: discarded\r\n",LogLevel.LOW);
return;
}
// discard non-SIP messages
String first_line=msg.getFirstLine();
if (first_line==null || first_line.toUpperCase().indexOf("SIP/2.0")<0)
{ if (log_all_packets) printLog("NOT a SIP message: discarded\r\n",LogLevel.LOW);
return;
}
printLog("received new SIP message",LogLevel.HIGH);
printLog("message:\r\n"+msg.toString(),LogLevel.LOWER);
// if a request, handle "received" and "rport" parameters
if (msg.isRequest())
{ ViaHeader vh=msg.getViaHeader();
boolean via_changed=false;
String src_addr=msg.getRemoteAddress();
int src_port=msg.getRemotePort();
String via_addr=vh.getHost();
int via_port=vh.getPort();
if (via_port<=0) via_port=SipStack.default_port;
if (!via_addr.equals(src_addr))
{ vh.setReceived(src_addr);
via_changed=true;
}
if (vh.hasRport())
{ vh.setRport(src_port);
via_changed=true;
}
else
{ if (force_rport && via_port!=src_port)
{ vh.setRport(src_port);
via_changed=true;
}
}
if (via_changed)
{ msg.removeViaHeader();
msg.addViaHeader(vh);
}
}
// is there any listeners?
if (listeners==null || listeners.size()==0)
{ printLog("no listener found: meesage discarded.",LogLevel.HIGH);
return;
}
// try to look for a UA in promisque mode
if (listeners.containsKey(PROMISQUE))
{ printLog("message passed to uas: "+PROMISQUE,LogLevel.MEDIUM);
((SipProviderListener)listeners.get(PROMISQUE)).onReceivedMessage(this,msg);
}
// after the callback check if the message is still valid
if (!msg.isRequest() && !msg.isResponse())
{ printLog("No valid SIP message: message discarded.",LogLevel.HIGH);
return;
}
// this was the promisque listener; now keep on looking for a tighter listener..
// try to look for a transaction
Identifier key=msg.getTransactionId();
printLog("DEBUG: transaction-id: "+key,LogLevel.MEDIUM);
if (listeners.containsKey(key))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -