use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SipProviderImpl method sendRequest.
/*
* (non-Javadoc)
*
* @see javax.sip.SipProvider#sendRequest(javax.sip.message.Request)
*/
public void sendRequest(Request request) throws SipException {
if (!sipStack.isAlive())
throw new SipException("Stack is stopped.");
// message.
if (((SIPRequest) request).getRequestLine() != null && request.getMethod().equals(Request.ACK)) {
Dialog dialog = sipStack.getDialog(((SIPRequest) request).getDialogId(false));
if (dialog != null && dialog.getState() != null) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logWarning("Dialog exists -- you may want to use Dialog.sendAck() " + dialog.getState());
}
}
Hop hop = sipStack.getRouter((SIPRequest) request).getNextHop(request);
if (hop == null)
throw new SipException("could not determine next hop!");
SIPRequest sipRequest = (SIPRequest) request;
// Null request is used to send default proxy keepalive messages.
if ((!sipRequest.isNullRequest()) && sipRequest.getTopmostVia() == null)
throw new SipException("Invalid SipRequest -- no via header!");
try {
/*
* JvB: Via branch should already be OK, dont touch it here? Some
* apps forward statelessly, and then it's not set. So set only when
* not set already, dont overwrite CANCEL branch here..
*/
if (!sipRequest.isNullRequest()) {
Via via = sipRequest.getTopmostVia();
String branch = via.getBranch();
if (branch == null || branch.length() == 0) {
via.setBranch(sipRequest.getTransactionId());
}
}
MessageChannel messageChannel = null;
if (this.listeningPoints.containsKey(hop.getTransport().toUpperCase()))
messageChannel = sipStack.createRawMessageChannel(this.getListeningPoint(hop.getTransport()).getIPAddress(), this.getListeningPoint(hop.getTransport()).getPort(), hop);
if (messageChannel != null) {
messageChannel.sendMessage((SIPMessage) sipRequest, hop);
} else {
throw new SipException("Could not create a message channel for " + hop.toString());
}
} catch (IOException ex) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logException(ex);
}
throw new SipException("IO Exception occured while Sending Request", ex);
} catch (ParseException ex1) {
InternalErrorHandler.handleException(ex1);
} finally {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("done sending " + request.getMethod() + " to hop " + hop);
}
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class AuthenticationHelperImpl method handleChallenge.
/*
* (non-Javadoc)
*
* @see gov.nist.javax.sip.clientauthutils.AuthenticationHelper#handleChallenge(javax.sip.message.Response,
* javax.sip.ClientTransaction, javax.sip.SipProvider)
*/
public ClientTransaction handleChallenge(Response challenge, ClientTransaction challengedTransaction, SipProvider transactionCreator, int cacheTime) throws SipException, NullPointerException {
try {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("handleChallenge: " + challenge);
}
SIPRequest challengedRequest = ((SIPRequest) challengedTransaction.getRequest());
Request reoriginatedRequest = null;
/*
* If the challenged request is part of a Dialog and the
* Dialog is confirmed the re-originated request should be
* generated as an in-Dialog request.
*/
if (challengedRequest.getToTag() != null || challengedTransaction.getDialog() == null || challengedTransaction.getDialog().getState() != DialogState.CONFIRMED) {
reoriginatedRequest = (Request) challengedRequest.clone();
} else {
/*
* Re-originate the request by consulting the dialog. In particular
* the route set could change between the original request and the
* in-dialog challenge.
*/
reoriginatedRequest = challengedTransaction.getDialog().createRequest(challengedRequest.getMethod());
Iterator<String> headerNames = challengedRequest.getHeaderNames();
while (headerNames.hasNext()) {
String headerName = headerNames.next();
if (reoriginatedRequest.getHeader(headerName) != null) {
ListIterator<Header> iterator = reoriginatedRequest.getHeaders(headerName);
while (iterator.hasNext()) {
reoriginatedRequest.addHeader(iterator.next());
}
}
}
}
// remove the branch id so that we could use the request in a new
// transaction
removeBranchID(reoriginatedRequest);
if (challenge == null || reoriginatedRequest == null) {
throw new NullPointerException("A null argument was passed to handle challenge.");
}
ListIterator authHeaders = null;
if (challenge.getStatusCode() == Response.UNAUTHORIZED) {
authHeaders = challenge.getHeaders(WWWAuthenticateHeader.NAME);
} else if (challenge.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED) {
authHeaders = challenge.getHeaders(ProxyAuthenticateHeader.NAME);
} else {
throw new IllegalArgumentException("Unexpected status code ");
}
if (authHeaders == null) {
throw new IllegalArgumentException("Could not find WWWAuthenticate or ProxyAuthenticate headers");
}
// Remove all authorization headers from the request (we'll re-add them
// from cache)
reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);
// rfc 3261 says that the cseq header should be augmented for the new
// request. do it here so that the new dialog (created together with
// the new client transaction) takes it into account.
// Bug report - Fredrik Wickstrom
CSeqHeader cSeq = (CSeqHeader) reoriginatedRequest.getHeader((CSeqHeader.NAME));
try {
cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l);
} catch (InvalidArgumentException ex) {
throw new SipException("Invalid CSeq -- could not increment : " + cSeq.getSeqNumber());
}
/* Resolve this to the next hop based on the previous lookup. If we are not using
* lose routing (RFC2543) then just attach hop as a maddr param.
*/
if (challengedRequest.getRouteHeaders() == null) {
Hop hop = ((SIPClientTransaction) challengedTransaction).getNextHop();
SipURI sipUri = (SipURI) reoriginatedRequest.getRequestURI();
// BEGIN android-added
if (!hop.getHost().equalsIgnoreCase(sipUri.getHost()) && !hop.equals(sipStack.getRouter(challengedRequest).getOutboundProxy()))
// END android-added
sipUri.setMAddrParam(hop.getHost());
if (hop.getPort() != -1)
sipUri.setPort(hop.getPort());
}
ClientTransaction retryTran = transactionCreator.getNewClientTransaction(reoriginatedRequest);
WWWAuthenticateHeader authHeader = null;
SipURI requestUri = (SipURI) challengedTransaction.getRequest().getRequestURI();
while (authHeaders.hasNext()) {
authHeader = (WWWAuthenticateHeader) authHeaders.next();
String realm = authHeader.getRealm();
AuthorizationHeader authorization = null;
String sipDomain;
if (this.accountManager instanceof SecureAccountManager) {
UserCredentialHash credHash = ((SecureAccountManager) this.accountManager).getCredentialHash(challengedTransaction, realm);
URI uri = reoriginatedRequest.getRequestURI();
sipDomain = credHash.getSipDomain();
authorization = this.getAuthorization(reoriginatedRequest.getMethod(), uri.toString(), (reoriginatedRequest.getContent() == null) ? "" : new String(reoriginatedRequest.getRawContent()), authHeader, credHash);
} else {
UserCredentials userCreds = ((AccountManager) this.accountManager).getCredentials(challengedTransaction, realm);
sipDomain = userCreds.getSipDomain();
if (userCreds == null)
throw new SipException("Cannot find user creds for the given user name and realm");
// we haven't yet authenticated this realm since we were
// started.
authorization = this.getAuthorization(reoriginatedRequest.getMethod(), reoriginatedRequest.getRequestURI().toString(), (reoriginatedRequest.getContent() == null) ? "" : new String(reoriginatedRequest.getRawContent()), authHeader, userCreds);
}
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Created authorization header: " + authorization.toString());
if (cacheTime != 0)
cachedCredentials.cacheAuthorizationHeader(sipDomain, authorization, cacheTime);
reoriginatedRequest.addHeader(authorization);
}
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Returning authorization transaction." + retryTran);
}
return retryTran;
} catch (SipException ex) {
throw ex;
} catch (Exception ex) {
sipStack.getStackLogger().logError("Unexpected exception ", ex);
throw new SipException("Unexpected exception ", ex);
}
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SipProviderImpl method getNewServerTransaction.
/*
* (non-Javadoc)
*
* @see javax.sip.SipProvider#getNewServerTransaction(javax.sip.message.Request)
*/
public ServerTransaction getNewServerTransaction(Request request) throws TransactionAlreadyExistsException, TransactionUnavailableException {
if (!sipStack.isAlive())
throw new TransactionUnavailableException("Stack is stopped");
SIPServerTransaction transaction = null;
SIPRequest sipRequest = (SIPRequest) request;
try {
sipRequest.checkHeaders();
} catch (ParseException ex) {
throw new TransactionUnavailableException(ex.getMessage(), ex);
}
if (request.getMethod().equals(Request.ACK)) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logError("Creating server transaction for ACK -- makes no sense!");
throw new TransactionUnavailableException("Cannot create Server transaction for ACK ");
}
/*
* Got a notify.
*/
if (sipRequest.getMethod().equals(Request.NOTIFY) && sipRequest.getFromTag() != null && sipRequest.getToTag() == null) {
SIPClientTransaction ct = sipStack.findSubscribeTransaction(sipRequest, (ListeningPointImpl) this.getListeningPoint());
/* Issue 104 */
if (ct == null && !sipStack.deliverUnsolicitedNotify) {
throw new TransactionUnavailableException("Cannot find matching Subscription (and gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY not set)");
}
}
if (!sipStack.acquireSem()) {
throw new TransactionUnavailableException("Transaction not available -- could not acquire stack lock");
}
try {
if (sipStack.isDialogCreated(sipRequest.getMethod())) {
if (sipStack.findTransaction((SIPRequest) request, true) != null)
throw new TransactionAlreadyExistsException("server transaction already exists!");
transaction = (SIPServerTransaction) ((SIPRequest) request).getTransaction();
if (transaction == null)
throw new TransactionUnavailableException("Transaction not available");
if (transaction.getOriginalRequest() == null)
transaction.setOriginalRequest(sipRequest);
try {
sipStack.addTransaction(transaction);
} catch (IOException ex) {
throw new TransactionUnavailableException("Error sending provisional response");
}
// So I can handle timeouts.
transaction.addEventListener(this);
if (isAutomaticDialogSupportEnabled()) {
// If automatic dialog support is enabled then
// this tx gets his own dialog.
String dialogId = sipRequest.getDialogId(true);
SIPDialog dialog = sipStack.getDialog(dialogId);
if (dialog == null) {
dialog = sipStack.createDialog(transaction);
}
transaction.setDialog(dialog, sipRequest.getDialogId(true));
if (sipRequest.getMethod().equals(Request.INVITE) && this.isDialogErrorsAutomaticallyHandled()) {
sipStack.putInMergeTable(transaction, sipRequest);
}
dialog.addRoute(sipRequest);
if (dialog.getRemoteTag() != null && dialog.getLocalTag() != null) {
this.sipStack.putDialog(dialog);
}
}
} else {
if (isAutomaticDialogSupportEnabled()) {
/*
* Under automatic dialog support, dialog is tied into a transaction. You cannot
* create a server tx except for dialog creating transactions. After that, all
* subsequent transactions are created for you by the stack.
*/
transaction = (SIPServerTransaction) sipStack.findTransaction((SIPRequest) request, true);
if (transaction != null)
throw new TransactionAlreadyExistsException("Transaction exists! ");
transaction = (SIPServerTransaction) ((SIPRequest) request).getTransaction();
if (transaction == null)
throw new TransactionUnavailableException("Transaction not available!");
if (transaction.getOriginalRequest() == null)
transaction.setOriginalRequest(sipRequest);
// Map the transaction.
try {
sipStack.addTransaction(transaction);
} catch (IOException ex) {
throw new TransactionUnavailableException("Could not send back provisional response!");
}
// If there is a dialog already assigned then just update the
// dialog state.
String dialogId = sipRequest.getDialogId(true);
SIPDialog dialog = sipStack.getDialog(dialogId);
if (dialog != null) {
dialog.addTransaction(transaction);
dialog.addRoute(sipRequest);
transaction.setDialog(dialog, sipRequest.getDialogId(true));
}
} else {
transaction = (SIPServerTransaction) sipStack.findTransaction((SIPRequest) request, true);
if (transaction != null)
throw new TransactionAlreadyExistsException("Transaction exists! ");
transaction = (SIPServerTransaction) ((SIPRequest) request).getTransaction();
if (transaction != null) {
if (transaction.getOriginalRequest() == null)
transaction.setOriginalRequest(sipRequest);
// Map the transaction.
sipStack.mapTransaction(transaction);
// If there is a dialog already assigned then just
// assign the dialog to the transaction.
String dialogId = sipRequest.getDialogId(true);
SIPDialog dialog = sipStack.getDialog(dialogId);
if (dialog != null) {
dialog.addTransaction(transaction);
dialog.addRoute(sipRequest);
transaction.setDialog(dialog, sipRequest.getDialogId(true));
}
return transaction;
} else {
// tx does not exist so create the tx.
MessageChannel mc = (MessageChannel) sipRequest.getMessageChannel();
transaction = sipStack.createServerTransaction(mc);
if (transaction == null)
throw new TransactionUnavailableException("Transaction unavailable -- too many servrer transactions");
transaction.setOriginalRequest(sipRequest);
sipStack.mapTransaction(transaction);
// If there is a dialog already assigned then just
// assign the dialog to the transaction.
String dialogId = sipRequest.getDialogId(true);
SIPDialog dialog = sipStack.getDialog(dialogId);
if (dialog != null) {
dialog.addTransaction(transaction);
dialog.addRoute(sipRequest);
transaction.setDialog(dialog, sipRequest.getDialogId(true));
}
return transaction;
}
}
}
return transaction;
} finally {
sipStack.releaseSem();
}
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SIPClientTransaction method createAck.
/*
* (non-Javadoc)
*
* @see javax.sip.ClientTransaction#createAck()
*/
public Request createAck() throws SipException {
SIPRequest originalRequest = this.getOriginalRequest();
if (originalRequest == null)
throw new SipException("bad state " + getState());
if (getMethod().equalsIgnoreCase(Request.ACK)) {
throw new SipException("Cannot ACK an ACK!");
} else if (lastResponse == null) {
throw new SipException("bad Transaction state");
} else if (lastResponse.getStatusCode() < 200) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("lastResponse = " + lastResponse);
}
throw new SipException("Cannot ACK a provisional response!");
}
SIPRequest ackRequest = originalRequest.createAckRequest((To) lastResponse.getTo());
// Pull the record route headers from the last reesponse.
RecordRouteList recordRouteList = lastResponse.getRecordRouteHeaders();
if (recordRouteList == null) {
// request URI.
if (lastResponse.getContactHeaders() != null && lastResponse.getStatusCode() / 100 != 3) {
Contact contact = (Contact) lastResponse.getContactHeaders().getFirst();
javax.sip.address.URI uri = (javax.sip.address.URI) contact.getAddress().getURI().clone();
ackRequest.setRequestURI(uri);
}
return ackRequest;
}
ackRequest.removeHeader(RouteHeader.NAME);
RouteList routeList = new RouteList();
// start at the end of the list and walk backwards
ListIterator<RecordRoute> li = recordRouteList.listIterator(recordRouteList.size());
while (li.hasPrevious()) {
RecordRoute rr = (RecordRoute) li.previous();
Route route = new Route();
route.setAddress((AddressImpl) ((AddressImpl) rr.getAddress()).clone());
route.setParameters((NameValueList) rr.getParameters().clone());
routeList.add(route);
}
Contact contact = null;
if (lastResponse.getContactHeaders() != null) {
contact = (Contact) lastResponse.getContactHeaders().getFirst();
}
if (!((SipURI) ((Route) routeList.getFirst()).getAddress().getURI()).hasLrParam()) {
// Contact may not yet be there (bug reported by Andreas B).
Route route = null;
if (contact != null) {
route = new Route();
route.setAddress((AddressImpl) ((AddressImpl) (contact.getAddress())).clone());
}
Route firstRoute = (Route) routeList.getFirst();
routeList.removeFirst();
javax.sip.address.URI uri = firstRoute.getAddress().getURI();
ackRequest.setRequestURI(uri);
if (route != null)
routeList.add(route);
ackRequest.addHeader(routeList);
} else {
if (contact != null) {
javax.sip.address.URI uri = (javax.sip.address.URI) contact.getAddress().getURI().clone();
ackRequest.setRequestURI(uri);
ackRequest.addHeader(routeList);
}
}
return ackRequest;
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SIPClientTransaction method sendMessage.
/**
* Send a request message through this transaction and onto the client.
*
* @param messageToSend Request to process and send.
*/
public void sendMessage(SIPMessage messageToSend) throws IOException {
try {
// Message typecast as a request
SIPRequest transactionRequest;
transactionRequest = (SIPRequest) messageToSend;
// Set the branch id for the top via header.
Via topVia = (Via) transactionRequest.getViaHeaders().getFirst();
// Tack on a branch identifier to match responses.
try {
topVia.setBranch(getBranch());
} catch (java.text.ParseException ex) {
}
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Sending Message " + messageToSend);
sipStack.getStackLogger().logDebug("TransactionState " + this.getState());
}
// If this is the first request for this transaction,
if (TransactionState.PROCEEDING == getState() || TransactionState.CALLING == getState()) {
// If this is a TU-generated ACK request,
if (transactionRequest.getMethod().equals(Request.ACK)) {
// transport and close this transaction
if (isReliable()) {
this.setState(TransactionState.TERMINATED);
} else {
this.setState(TransactionState.COMPLETED);
}
// BUGBUG -- This suppresses sending the ACK uncomment this
// to
// test 4xx retransmission
// if (transactionRequest.getMethod() != Request.ACK)
super.sendMessage(transactionRequest);
return;
}
}
try {
// Send the message to the server
lastRequest = transactionRequest;
if (getState() == null) {
// Save this request as the one this transaction
// is handling
setOriginalRequest(transactionRequest);
if (transactionRequest.getMethod().equals(Request.INVITE)) {
this.setState(TransactionState.CALLING);
} else if (transactionRequest.getMethod().equals(Request.ACK)) {
// Acks are never retransmitted.
this.setState(TransactionState.TERMINATED);
} else {
this.setState(TransactionState.TRYING);
}
if (!isReliable()) {
enableRetransmissionTimer();
}
if (isInviteTransaction()) {
enableTimeoutTimer(TIMER_B);
} else {
enableTimeoutTimer(TIMER_F);
}
}
// BUGBUG This supresses sending ACKS -- uncomment to test
// 4xx retransmission.
// if (transactionRequest.getMethod() != Request.ACK)
super.sendMessage(transactionRequest);
} catch (IOException e) {
this.setState(TransactionState.TERMINATED);
throw e;
}
} finally {
this.isMapped = true;
this.startTransactionTimer();
}
}
Aggregations