use of javax.sip.address.SipURI in project XobotOS by xamarin.
the class SipUri method equals.
/**
* Compare two URIs and return true if they are equal.
* @param that the object to compare to.
* @return true if the object is equal to this object.
*
* JvB: Updated to define equality in terms of API methods, according to the rules
* in RFC3261 section 19.1.4
*
* Jean Deruelle: Updated to define equality of API methods, according to the rules
* in RFC3261 section 19.1.4 convert potential ie :
* %HEX HEX encoding parts of the URI before comparing them
* transport param added in comparison
* header equality enforced in comparison
*
*/
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object that) {
// Shortcut for same object
if (that == this)
return true;
if (that instanceof SipURI) {
final SipURI a = this;
final SipURI b = (SipURI) that;
// A SIP and SIPS URI are never equivalent
if (a.isSecure() ^ b.isSecure())
return false;
// components must match; comparison of userinfo is case-sensitive
if (a.getUser() == null ^ b.getUser() == null)
return false;
if (a.getUserPassword() == null ^ b.getUserPassword() == null)
return false;
if (a.getUser() != null && !RFC2396UrlDecoder.decode(a.getUser()).equals(RFC2396UrlDecoder.decode(b.getUser())))
return false;
if (a.getUserPassword() != null && !RFC2396UrlDecoder.decode(a.getUserPassword()).equals(RFC2396UrlDecoder.decode(b.getUserPassword())))
return false;
if (a.getHost() == null ^ b.getHost() == null)
return false;
if (a.getHost() != null && !a.getHost().equalsIgnoreCase(b.getHost()))
return false;
if (a.getPort() != b.getPort())
return false;
// URI parameters
for (Iterator i = a.getParameterNames(); i.hasNext(); ) {
String pname = (String) i.next();
String p1 = a.getParameter(pname);
String p2 = b.getParameter(pname);
// those present in both must match (case-insensitive)
if (p1 != null && p2 != null && !RFC2396UrlDecoder.decode(p1).equalsIgnoreCase(RFC2396UrlDecoder.decode(p2)))
return false;
}
// transport, user, ttl or method must match when present in either
if (a.getTransportParam() == null ^ b.getTransportParam() == null)
return false;
if (a.getUserParam() == null ^ b.getUserParam() == null)
return false;
if (a.getTTLParam() == -1 ^ b.getTTLParam() == -1)
return false;
if (a.getMethodParam() == null ^ b.getMethodParam() == null)
return false;
if (a.getMAddrParam() == null ^ b.getMAddrParam() == null)
return false;
// Headers: must match according to their definition.
if (a.getHeaderNames().hasNext() && !b.getHeaderNames().hasNext())
return false;
if (!a.getHeaderNames().hasNext() && b.getHeaderNames().hasNext())
return false;
if (a.getHeaderNames().hasNext() && b.getHeaderNames().hasNext()) {
HeaderFactory headerFactory = null;
try {
headerFactory = SipFactory.getInstance().createHeaderFactory();
} catch (PeerUnavailableException e) {
Debug.logError("Cannot get the header factory to parse the header of the sip uris to compare", e);
return false;
}
for (Iterator i = a.getHeaderNames(); i.hasNext(); ) {
String hname = (String) i.next();
String h1 = a.getHeader(hname);
String h2 = b.getHeader(hname);
if (h1 == null && h2 != null)
return false;
if (h2 == null && h1 != null)
return false;
// The following check should not be needed but we add it for findbugs.
if (h1 == null && h2 == null)
continue;
try {
Header header1 = headerFactory.createHeader(hname, RFC2396UrlDecoder.decode(h1));
Header header2 = headerFactory.createHeader(hname, RFC2396UrlDecoder.decode(h2));
// those present in both must match according to the equals method of the corresponding header
if (!header1.equals(header2))
return false;
} catch (ParseException e) {
Debug.logError("Cannot parse one of the header of the sip uris to compare " + a + " " + b, e);
return false;
}
}
}
// Finally, we can conclude that they are indeed equal
return true;
}
return false;
}
use of javax.sip.address.SipURI in project XobotOS by xamarin.
the class ListeningPointImpl method createContactHeader.
public ContactHeader createContactHeader() {
try {
String ipAddress = this.getIPAddress();
int port = this.getPort();
SipURI sipURI = new SipUri();
sipURI.setHost(ipAddress);
sipURI.setPort(port);
sipURI.setTransportParam(this.transport);
Contact contact = new Contact();
AddressImpl address = new AddressImpl();
address.setURI(sipURI);
contact.setAddress(address);
return contact;
} catch (Exception ex) {
InternalErrorHandler.handleException("Unexpected exception", sipStack.getStackLogger());
return null;
}
}
use of javax.sip.address.SipURI in project XobotOS by xamarin.
the class SIPDialog method addRoute.
/**
* Add a route list extracted from a record route list. If this is a server dialog then we
* assume that the record are added to the route list IN order. If this is a client dialog
* then we assume that the record route headers give us the route list to add in reverse
* order.
*
* @param recordRouteList -- the record route list from the incoming message.
*/
private void addRoute(RecordRouteList recordRouteList) {
try {
if (this.isClientDialog()) {
// This is a client dialog so we extract the record
// route from the response and reverse its order to
// careate a route list.
this.routeList = new RouteList();
// start at the end of the list and walk backwards
ListIterator li = recordRouteList.listIterator(recordRouteList.size());
boolean addRoute = true;
while (li.hasPrevious()) {
RecordRoute rr = (RecordRoute) li.previous();
if (addRoute) {
Route route = new Route();
AddressImpl address = ((AddressImpl) ((AddressImpl) rr.getAddress()).clone());
route.setAddress(address);
route.setParameters((NameValueList) rr.getParameters().clone());
this.routeList.add(route);
}
}
} else {
// This is a server dialog. The top most record route
// header is the one that is closest to us. We extract the
// route list in the same order as the addresses in the
// incoming request.
this.routeList = new RouteList();
ListIterator li = recordRouteList.listIterator();
boolean addRoute = true;
while (li.hasNext()) {
RecordRoute rr = (RecordRoute) li.next();
if (addRoute) {
Route route = new Route();
AddressImpl address = ((AddressImpl) ((AddressImpl) rr.getAddress()).clone());
route.setAddress(address);
route.setParameters((NameValueList) rr.getParameters().clone());
routeList.add(route);
}
}
}
} finally {
if (sipStack.getStackLogger().isLoggingEnabled()) {
Iterator it = routeList.iterator();
while (it.hasNext()) {
SipURI sipUri = (SipURI) (((Route) it.next()).getAddress().getURI());
if (!sipUri.hasLrParam()) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logWarning("NON LR route in Route set detected for dialog : " + this);
sipStack.getStackLogger().logStackTrace();
}
}
}
}
}
}
use of javax.sip.address.SipURI in project XobotOS by xamarin.
the class SIPDialog method createAck.
/*
* (non-Javadoc) The UAC core MUST generate an ACK request for each 2xx received from the
* transaction layer. The header fields of the ACK are constructed in the same way as for any
* request sent within a dialog (see Section 12) with the exception of the CSeq and the header
* fields related to authentication. The sequence number of the CSeq header field MUST be the
* same as the INVITE being acknowledged, but the CSeq method MUST be ACK. The ACK MUST
* contain the same credentials as the INVITE. If the 2xx contains an offer (based on the
* rules above), the ACK MUST carry an answer in its body. If the offer in the 2xx response is
* not acceptable, the UAC core MUST generate a valid answer in the ACK and then send a BYE
* immediately.
*
* Note that for the case of forked requests, you can create multiple outgoing invites each
* with a different cseq and hence you need to supply the invite.
*
* @see javax.sip.Dialog#createAck(long)
*/
public Request createAck(long cseqno) throws InvalidArgumentException, SipException {
// then send INVITE+ACK later on
if (!method.equals(Request.INVITE))
throw new SipException("Dialog was not created with an INVITE" + method);
if (cseqno <= 0)
throw new InvalidArgumentException("bad cseq <= 0 ");
else if (cseqno > ((((long) 1) << 32) - 1))
throw new InvalidArgumentException("bad cseq > " + ((((long) 1) << 32) - 1));
if (this.remoteTarget == null) {
throw new SipException("Cannot create ACK - no remote Target!");
}
if (this.sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("createAck " + this + " cseqno " + cseqno);
}
// out of order ACK sending. Old ACKs seqno's can always be ACKed.
if (lastInviteOkReceived < cseqno) {
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("WARNING : Attempt to crete ACK without OK " + this);
this.sipStack.getStackLogger().logDebug("LAST RESPONSE = " + this.lastResponse);
}
throw new SipException("Dialog not yet established -- no OK response!");
}
try {
// JvB: Transport from first entry in route set, or remote Contact
// if none
// Only used to find correct LP & create correct Via
SipURI uri4transport = null;
if (this.routeList != null && !this.routeList.isEmpty()) {
Route r = (Route) this.routeList.getFirst();
uri4transport = ((SipURI) r.getAddress().getURI());
} else {
// should be !=null, checked above
uri4transport = ((SipURI) this.remoteTarget.getURI());
}
String transport = uri4transport.getTransportParam();
if (transport == null) {
// JvB fix: also support TLS
transport = uri4transport.isSecure() ? ListeningPoint.TLS : ListeningPoint.UDP;
}
ListeningPointImpl lp = (ListeningPointImpl) sipProvider.getListeningPoint(transport);
if (lp == null) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logError("remoteTargetURI " + this.remoteTarget.getURI());
sipStack.getStackLogger().logError("uri4transport = " + uri4transport);
sipStack.getStackLogger().logError("No LP found for transport=" + transport);
}
throw new SipException("Cannot create ACK - no ListeningPoint for transport towards next hop found:" + transport);
}
SIPRequest sipRequest = new SIPRequest();
sipRequest.setMethod(Request.ACK);
sipRequest.setRequestURI((SipUri) getRemoteTarget().getURI().clone());
sipRequest.setCallId(this.callIdHeader);
sipRequest.setCSeq(new CSeq(cseqno, Request.ACK));
List<Via> vias = new ArrayList<Via>();
// Via via = lp.getViaHeader();
// The user may have touched the sentby for the response.
// so use the via header extracted from the response for the ACK =>
// https://jain-sip.dev.java.net/issues/show_bug.cgi?id=205
// strip the params from the via of the response and use the params from the
// original request
Via via = this.lastResponse.getTopmostVia();
via.removeParameters();
if (originalRequest != null && originalRequest.getTopmostVia() != null) {
NameValueList originalRequestParameters = originalRequest.getTopmostVia().getParameters();
if (originalRequestParameters != null && originalRequestParameters.size() > 0) {
via.setParameters((NameValueList) originalRequestParameters.clone());
}
}
// new branch
via.setBranch(Utils.getInstance().generateBranchId());
vias.add(via);
sipRequest.setVia(vias);
From from = new From();
from.setAddress(this.localParty);
from.setTag(this.myTag);
sipRequest.setFrom(from);
To to = new To();
to.setAddress(this.remoteParty);
if (hisTag != null)
to.setTag(this.hisTag);
sipRequest.setTo(to);
sipRequest.setMaxForwards(new MaxForwards(70));
if (this.originalRequest != null) {
Authorization authorization = this.originalRequest.getAuthorization();
if (authorization != null)
sipRequest.setHeader(authorization);
}
// ACKs for 2xx responses
// use the Route values learned from the Record-Route of the 2xx
// responses.
this.updateRequest(sipRequest);
return sipRequest;
} catch (Exception ex) {
InternalErrorHandler.handleException(ex);
throw new SipException("unexpected exception ", ex);
}
}
use of javax.sip.address.SipURI in project Openfire by igniterealtime.
the class SipCommRouter method getNextHops.
/**
* Return the default address to forward the request to. The list is
* organized in the following priority.
* <p/>
* If the outboung proxy has been specified, then it is used to construct
* the first element of the list.
* <p/>
* If the requestURI refers directly to a host, the host and port
* information are extracted from it and made the next hop on the list.
*
* @param sipRequest is the sip request to route.
*/
public ListIterator<Hop> getNextHops(Request sipRequest) {
URI requestURI = sipRequest.getRequestURI();
if (requestURI == null) {
throw new IllegalArgumentException("Bad message: Null requestURI");
}
LinkedList<Hop> hops = new LinkedList<Hop>();
if (outboundProxy != null) {
hops.add(outboundProxy);
}
ListIterator routes = sipRequest.getHeaders(RouteHeader.NAME);
if (routes != null && routes.hasNext()) {
while (routes.hasNext()) {
RouteHeader route = (RouteHeader) routes.next();
SipURI uri = (SipURI) route.getAddress().getURI();
int port = uri.getPort();
port = (port == -1) ? 5060 : port;
String host = uri.getHost();
Log.debug("getNextHops", host);
String transport = uri.getTransportParam();
if (transport == null) {
transport = "udp";
}
Hop hop = new SipCommHop(host + ':' + port + '/' + transport);
hops.add(hop);
}
} else if (requestURI instanceof SipURI && ((SipURI) requestURI).getMAddrParam() != null) {
SipURI sipURI = ((SipURI) requestURI);
String maddr = sipURI.getMAddrParam();
String transport = sipURI.getTransportParam();
if (transport == null) {
transport = "udp";
}
int port = 5060;
Hop hop = new SipCommHop(maddr, port, transport);
hops.add(hop);
} else if (requestURI instanceof SipURI) {
SipURI sipURI = ((SipURI) requestURI);
int port = sipURI.getPort();
if (port == -1) {
port = 5060;
}
String host = sipURI.getHost();
String transport = sipURI.getTransportParam();
if (transport == null) {
transport = "UDP";
}
Hop hop = new SipCommHop(host + ":" + port + "/" + transport);
hops.add(hop);
} else {
throw new IllegalArgumentException("Malformed requestURI");
}
return (hops.size() == 0) ? null : hops.listIterator();
}
Aggregations