use of gov.nist.javax.sip.header.To 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 gov.nist.javax.sip.header.To in project XobotOS by xamarin.
the class SIPDialog method sendRequest.
public void sendRequest(ClientTransaction clientTransactionId, boolean allowInterleaving) throws TransactionDoesNotExistException, SipException {
if ((!allowInterleaving) && clientTransactionId.getRequest().getMethod().equals(Request.INVITE)) {
new Thread((new ReInviteSender(clientTransactionId))).start();
return;
}
SIPRequest dialogRequest = ((SIPClientTransaction) clientTransactionId).getOriginalRequest();
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("dialog.sendRequest " + " dialog = " + this + "\ndialogRequest = \n" + dialogRequest);
if (clientTransactionId == null)
throw new NullPointerException("null parameter");
if (dialogRequest.getMethod().equals(Request.ACK) || dialogRequest.getMethod().equals(Request.CANCEL))
throw new SipException("Bad Request Method. " + dialogRequest.getMethod());
// JvB: added, allow re-sending of BYE after challenge
if (byeSent && isTerminatedOnBye() && !dialogRequest.getMethod().equals(Request.BYE)) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logError("BYE already sent for " + this);
throw new SipException("Cannot send request; BYE already sent");
}
if (dialogRequest.getTopmostVia() == null) {
Via via = ((SIPClientTransaction) clientTransactionId).getOutgoingViaHeader();
dialogRequest.addHeader(via);
}
if (!this.getCallId().getCallId().equalsIgnoreCase(dialogRequest.getCallId().getCallId())) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logError("CallID " + this.getCallId());
sipStack.getStackLogger().logError("RequestCallID = " + dialogRequest.getCallId().getCallId());
sipStack.getStackLogger().logError("dialog = " + this);
}
throw new SipException("Bad call ID in request");
}
// Set the dialog back pointer.
((SIPClientTransaction) clientTransactionId).setDialog(this, this.dialogId);
this.addTransaction((SIPTransaction) clientTransactionId);
// Enable the retransmission filter for the transaction
((SIPClientTransaction) clientTransactionId).isMapped = true;
From from = (From) dialogRequest.getFrom();
To to = (To) dialogRequest.getTo();
// tag assignment is OK.
if (this.getLocalTag() != null && from.getTag() != null && !from.getTag().equals(this.getLocalTag()))
throw new SipException("From tag mismatch expecting " + this.getLocalTag());
if (this.getRemoteTag() != null && to.getTag() != null && !to.getTag().equals(this.getRemoteTag())) {
if (sipStack.isLoggingEnabled())
this.sipStack.getStackLogger().logWarning("To header tag mismatch expecting " + this.getRemoteTag());
}
/*
* The application is sending a NOTIFY before sending the response of the dialog.
*/
if (this.getLocalTag() == null && dialogRequest.getMethod().equals(Request.NOTIFY)) {
if (!this.getMethod().equals(Request.SUBSCRIBE))
throw new SipException("Trying to send NOTIFY without SUBSCRIBE Dialog!");
this.setLocalTag(from.getTag());
}
try {
if (this.getLocalTag() != null)
from.setTag(this.getLocalTag());
if (this.getRemoteTag() != null)
to.setTag(this.getRemoteTag());
} catch (ParseException ex) {
InternalErrorHandler.handleException(ex);
}
Hop hop = ((SIPClientTransaction) clientTransactionId).getNextHop();
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Using hop = " + hop.getHost() + " : " + hop.getPort());
}
try {
MessageChannel messageChannel = sipStack.createRawMessageChannel(this.getSipProvider().getListeningPoint(hop.getTransport()).getIPAddress(), this.firstTransactionPort, hop);
MessageChannel oldChannel = ((SIPClientTransaction) clientTransactionId).getMessageChannel();
// Remove this from the connection cache if it is in the
// connection
// cache and is not yet active.
oldChannel.uncache();
// Not configured to cache client connections.
if (!sipStack.cacheClientConnections) {
oldChannel.useCount--;
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("oldChannel: useCount " + oldChannel.useCount);
}
if (messageChannel == null) {
/*
* At this point the procedures of 8.1.2 and 12.2.1.1 of RFC3261 have been tried
* but the resulting next hop cannot be resolved (recall that the exception thrown
* is caught and ignored in SIPStack.createMessageChannel() so we end up here with
* a null messageChannel instead of the exception handler below). All else
* failing, try the outbound proxy in accordance with 8.1.2, in particular: This
* ensures that outbound proxies that do not add Record-Route header field values
* will drop out of the path of subsequent requests. It allows endpoints that
* cannot resolve the first Route URI to delegate that task to an outbound proxy.
*
* if one considers the 'first Route URI' of a request constructed according to
* 12.2.1.1 to be the request URI when the route set is empty.
*/
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Null message channel using outbound proxy !");
Hop outboundProxy = sipStack.getRouter(dialogRequest).getOutboundProxy();
if (outboundProxy == null)
throw new SipException("No route found! hop=" + hop);
messageChannel = sipStack.createRawMessageChannel(this.getSipProvider().getListeningPoint(outboundProxy.getTransport()).getIPAddress(), this.firstTransactionPort, outboundProxy);
if (messageChannel != null)
((SIPClientTransaction) clientTransactionId).setEncapsulatedChannel(messageChannel);
} else {
((SIPClientTransaction) clientTransactionId).setEncapsulatedChannel(messageChannel);
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("using message channel " + messageChannel);
}
}
if (messageChannel != null)
messageChannel.useCount++;
// See if we need to release the previously mapped channel.
if ((!sipStack.cacheClientConnections) && oldChannel != null && oldChannel.useCount <= 0)
oldChannel.close();
} catch (Exception ex) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logException(ex);
throw new SipException("Could not create message channel", ex);
}
try {
// Increment before setting!!
localSequenceNumber++;
dialogRequest.getCSeq().setSeqNumber(getLocalSeqNumber());
} catch (InvalidArgumentException ex) {
sipStack.getStackLogger().logFatalError(ex.getMessage());
}
try {
((SIPClientTransaction) clientTransactionId).sendMessage(dialogRequest);
/*
* Note that if the BYE is rejected then the Dialog should bo back to the ESTABLISHED
* state so we only set state after successful send.
*/
if (dialogRequest.getMethod().equals(Request.BYE)) {
this.byeSent = true;
/*
* Dialog goes into TERMINATED state as soon as BYE is sent. ISSUE 182.
*/
if (isTerminatedOnBye()) {
this.setState(DialogState._TERMINATED);
}
}
} catch (IOException ex) {
throw new SipException("error sending message", ex);
}
}
use of gov.nist.javax.sip.header.To in project XobotOS by xamarin.
the class SIPMessage method removeHeader.
/**
* Remove a header given its name. If multiple headers of a given name are present then the
* top flag determines which end to remove headers from.
*
* @param headerName is the name of the header to remove.
* @param top -- flag that indicates which end of header list to process.
*/
public void removeHeader(String headerName, boolean top) {
String headerNameLowerCase = SIPHeaderNamesCache.toLowerCase(headerName);
SIPHeader toRemove = (SIPHeader) nameTable.get(headerNameLowerCase);
// nothing to do then we are done.
if (toRemove == null)
return;
if (toRemove instanceof SIPHeaderList) {
SIPHeaderList<?> hdrList = (SIPHeaderList<?>) toRemove;
if (top)
hdrList.removeFirst();
else
hdrList.removeLast();
// Clean up empty list
if (hdrList.isEmpty()) {
Iterator<SIPHeader> li = this.headers.iterator();
while (li.hasNext()) {
SIPHeader sipHeader = (SIPHeader) li.next();
if (sipHeader.getName().equalsIgnoreCase(headerNameLowerCase))
li.remove();
}
// JvB: also remove it from the nameTable! Else NPE in
// DefaultRouter
nameTable.remove(headerNameLowerCase);
}
} else {
this.nameTable.remove(headerNameLowerCase);
if (toRemove instanceof From) {
this.fromHeader = null;
} else if (toRemove instanceof To) {
this.toHeader = null;
} else if (toRemove instanceof CSeq) {
this.cSeqHeader = null;
} else if (toRemove instanceof CallID) {
this.callIdHeader = null;
} else if (toRemove instanceof MaxForwards) {
this.maxForwardsHeader = null;
} else if (toRemove instanceof ContentLength) {
this.contentLengthHeader = null;
}
Iterator<SIPHeader> li = this.headers.iterator();
while (li.hasNext()) {
SIPHeader sipHeader = (SIPHeader) li.next();
if (sipHeader.getName().equalsIgnoreCase(headerName))
li.remove();
}
}
}
use of gov.nist.javax.sip.header.To in project XobotOS by xamarin.
the class SIPMessage method removeHeader.
/**
* Remove all headers given its name.
*
* @param headerName is the name of the header to remove.
*/
public void removeHeader(String headerName) {
if (headerName == null)
throw new NullPointerException("null arg");
String headerNameLowerCase = SIPHeaderNamesCache.toLowerCase(headerName);
SIPHeader removed = (SIPHeader) nameTable.remove(headerNameLowerCase);
// nothing to do then we are done.
if (removed == null)
return;
// Remove the fast accessor fields.
if (removed instanceof From) {
this.fromHeader = null;
} else if (removed instanceof To) {
this.toHeader = null;
} else if (removed instanceof CSeq) {
this.cSeqHeader = null;
} else if (removed instanceof CallID) {
this.callIdHeader = null;
} else if (removed instanceof MaxForwards) {
this.maxForwardsHeader = null;
} else if (removed instanceof ContentLength) {
this.contentLengthHeader = null;
}
Iterator<SIPHeader> li = this.headers.iterator();
while (li.hasNext()) {
SIPHeader sipHeader = (SIPHeader) li.next();
if (sipHeader.getName().equalsIgnoreCase(headerNameLowerCase))
li.remove();
}
}
use of gov.nist.javax.sip.header.To in project XobotOS by xamarin.
the class SIPMessage method attachHeader.
/**
* Attach the header to the SIP Message structure at a specified position in its list of
* headers.
*
* @param header Header to attach.
* @param replaceFlag If true then replace the existing header.
* @param top Location in the header list to insert the header.
* @exception SIPDuplicateHeaderException if the header is of a type that cannot tolerate
* duplicates and one of this type already exists (e.g. CSeq header).
* @throws IndexOutOfBoundsException If the index specified is greater than the number of
* headers that are in this message.
*/
public void attachHeader(SIPHeader header, boolean replaceFlag, boolean top) throws SIPDuplicateHeaderException {
if (header == null) {
throw new NullPointerException("null header");
}
SIPHeader h;
if (ListMap.hasList(header) && !SIPHeaderList.class.isAssignableFrom(header.getClass())) {
SIPHeaderList<SIPHeader> hdrList = ListMap.getList(header);
hdrList.add(header);
h = hdrList;
} else {
h = header;
}
String headerNameLowerCase = SIPHeaderNamesCache.toLowerCase(h.getName());
if (replaceFlag) {
nameTable.remove(headerNameLowerCase);
} else if (nameTable.containsKey(headerNameLowerCase) && !(h instanceof SIPHeaderList)) {
if (h instanceof ContentLength) {
try {
ContentLength cl = (ContentLength) h;
contentLengthHeader.setContentLength(cl.getContentLength());
} catch (InvalidArgumentException e) {
}
}
// Just ignore duplicate header.
return;
}
SIPHeader originalHeader = (SIPHeader) getHeader(header.getName());
// Delete the original header from our list structure.
if (originalHeader != null) {
Iterator<SIPHeader> li = headers.iterator();
while (li.hasNext()) {
SIPHeader next = (SIPHeader) li.next();
if (next.equals(originalHeader)) {
li.remove();
}
}
}
if (!nameTable.containsKey(headerNameLowerCase)) {
nameTable.put(headerNameLowerCase, h);
headers.add(h);
} else {
if (h instanceof SIPHeaderList) {
SIPHeaderList<?> hdrlist = (SIPHeaderList<?>) nameTable.get(headerNameLowerCase);
if (hdrlist != null)
hdrlist.concatenate((SIPHeaderList) h, top);
else
nameTable.put(headerNameLowerCase, h);
} else {
nameTable.put(headerNameLowerCase, h);
}
}
// Direct accessor fields for frequently accessed headers.
if (h instanceof From) {
this.fromHeader = (From) h;
} else if (h instanceof ContentLength) {
this.contentLengthHeader = (ContentLength) h;
} else if (h instanceof To) {
this.toHeader = (To) h;
} else if (h instanceof CSeq) {
this.cSeqHeader = (CSeq) h;
} else if (h instanceof CallID) {
this.callIdHeader = (CallID) h;
} else if (h instanceof MaxForwards) {
this.maxForwardsHeader = (MaxForwards) h;
}
}
Aggregations