Package gov.nist.javax.sip.message

Source Code of gov.nist.javax.sip.message.SIPResponse

/*
* Conditions Of Use
*
* This software was developed by employees of the National Institute of
* Standards and Technology (NIST), an agency of the Federal Government.
* Pursuant to title 15 Untied States Code Section 105, works of NIST
* employees are not subject to copyright protection in the United States
* and are considered to be in the public domain.  As a result, a formal
* license is not needed to use the software.
*
* This software is provided by NIST as a service and is expressly
* provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY.  NIST does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
* Permission to use this software is contingent upon your acceptance
* of the terms of this agreement
* .
*
*/
/*******************************************************************************
* Product of NIST/ITL Advanced Networking Technologies Division (ANTD)         *
*******************************************************************************/
package gov.nist.javax.sip.message;

import gov.nist.core.InternalErrorHandler;
import gov.nist.javax.sip.Utils;
import gov.nist.javax.sip.address.SipUri;
import gov.nist.javax.sip.header.CSeq;
import gov.nist.javax.sip.header.CallID;
import gov.nist.javax.sip.header.ContactList;
import gov.nist.javax.sip.header.ContentLength;
import gov.nist.javax.sip.header.ContentType;
import gov.nist.javax.sip.header.From;
import gov.nist.javax.sip.header.MaxForwards;
import gov.nist.javax.sip.header.ReasonList;
import gov.nist.javax.sip.header.RecordRouteList;
import gov.nist.javax.sip.header.RequireList;
import gov.nist.javax.sip.header.SIPHeader;
import gov.nist.javax.sip.header.StatusLine;
import gov.nist.javax.sip.header.To;
import gov.nist.javax.sip.header.Via;
import gov.nist.javax.sip.header.ViaList;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Iterator;
import java.util.LinkedList;

import javax.sip.header.ReasonHeader;
import javax.sip.header.ServerHeader;
import javax.sip.message.Request;


/**
* SIP Response structure.
*
* @version 1.2 $Revision: 1.26 $ $Date: 2009/05/11 18:52:41 $
* @since 1.1
*
* @author M. Ranganathan   <br/>
*
*
*/
public final class SIPResponse
  extends SIPMessage
  implements javax.sip.message.Response {
  protected StatusLine statusLine;
 
  public static String getReasonPhrase(int rc) {
    String retval = null;
    switch (rc) {

      case TRYING :
        retval = "Trying";
        break;

      case RINGING :
        retval = "Ringing";
        break;

      case CALL_IS_BEING_FORWARDED :
        retval = "Call is being forwarded";
        break;

      case QUEUED :
        retval = "Queued";
        break;

      case SESSION_PROGRESS :
        retval = "Session progress";
        break;

      case OK :
        retval = "OK";
        break;

      case ACCEPTED :
        retval = "Accepted";
        break;

      case MULTIPLE_CHOICES :
        retval = "Multiple choices";
        break;

      case MOVED_PERMANENTLY :
        retval = "Moved permanently";
        break;

      case MOVED_TEMPORARILY :
        retval = "Moved Temporarily";
        break;

      case USE_PROXY :
        retval = "Use proxy";
        break;

      case ALTERNATIVE_SERVICE :
        retval = "Alternative service";
        break;

      case BAD_REQUEST :
        retval = "Bad request";
        break;

      case UNAUTHORIZED :
        retval = "Unauthorized";
        break;

      case PAYMENT_REQUIRED :
        retval = "Payment required";
        break;

      case FORBIDDEN :
        retval = "Forbidden";
        break;

      case NOT_FOUND :
        retval = "Not found";
        break;

      case METHOD_NOT_ALLOWED :
        retval = "Method not allowed";
        break;

      case NOT_ACCEPTABLE :
        retval = "Not acceptable";
        break;

      case PROXY_AUTHENTICATION_REQUIRED :
        retval = "Proxy Authentication required";
        break;

      case REQUEST_TIMEOUT :
        retval = "Request timeout";
        break;

      case GONE :
        retval = "Gone";
        break;

      case TEMPORARILY_UNAVAILABLE :
        retval = "Temporarily Unavailable";
        break;

      case REQUEST_ENTITY_TOO_LARGE :
        retval = "Request entity too large";
        break;

      case REQUEST_URI_TOO_LONG :
        retval = "Request-URI too large";
        break;

      case UNSUPPORTED_MEDIA_TYPE :
        retval = "Unsupported media type";
        break;

      case UNSUPPORTED_URI_SCHEME :
        retval = "Unsupported URI Scheme";
        break;

      case BAD_EXTENSION :
        retval = "Bad extension";
        break;

      case EXTENSION_REQUIRED :
        retval = "Etension Required";
        break;

      case INTERVAL_TOO_BRIEF :
        retval = "Interval too brief";
        break;

      case CALL_OR_TRANSACTION_DOES_NOT_EXIST :
        retval = "Call leg/Transaction does not exist";
        break;

      case LOOP_DETECTED :
        retval = "Loop detected";
        break;

      case TOO_MANY_HOPS :
        retval = "Too many hops";
        break;

      case ADDRESS_INCOMPLETE :
        retval = "Address incomplete";
        break;

      case AMBIGUOUS :
        retval = "Ambiguous";
        break;

      case BUSY_HERE :
        retval = "Busy here";
        break;

      case REQUEST_TERMINATED :
        retval = "Request Terminated";
        break;

      //Issue 168, Typo fix reported by fre on the retval
      case NOT_ACCEPTABLE_HERE :       
        retval = "Not Acceptable here";
        break;

      case BAD_EVENT :
        retval = "Bad Event";
        break;

      case REQUEST_PENDING :
        retval = "Request Pending";
        break;

      case SERVER_INTERNAL_ERROR :
        retval = "Server Internal Error";
        break;

      case UNDECIPHERABLE :
        retval = "Undecipherable";
        break;

      case NOT_IMPLEMENTED :
        retval = "Not implemented";
        break;

      case BAD_GATEWAY :
        retval = "Bad gateway";
        break;

      case SERVICE_UNAVAILABLE :
        retval = "Service unavailable";
        break;

      case SERVER_TIMEOUT :
        retval = "Gateway timeout";
        break;

      case VERSION_NOT_SUPPORTED :
        retval = "SIP version not supported";
        break;

      case MESSAGE_TOO_LARGE :
        retval = "Message Too Large";
        break;

      case BUSY_EVERYWHERE :
        retval = "Busy everywhere";
        break;

      case DECLINE :
        retval = "Decline";
        break;

      case DOES_NOT_EXIST_ANYWHERE :
        retval = "Does not exist anywhere";
        break;

      case SESSION_NOT_ACCEPTABLE :
        retval = "Session Not acceptable";
        break;

      case CONDITIONAL_REQUEST_FAILED:
        retval = "Conditional request failed";
        break;
       
      default :
        retval = "Unknown Status";

    }
    return retval;

  }

  /** set the status code.
   *@param statusCode is the status code to set.
   *@throws IlegalArgumentException if invalid status code.
   */
  public void setStatusCode(int statusCode) throws ParseException {
   
    // RFC3261 defines statuscode as 3DIGIT, 606 is the highest officially
    // defined code but extensions may add others (in theory up to 999,
    // but in practice up to 699 since the 6xx range is defined as 'final error')
    if (statusCode < 100 || statusCode > 699)
      throw new ParseException("bad status code", 0);
    if (this.statusLine == null)
      this.statusLine = new StatusLine();
    this.statusLine.setStatusCode(statusCode);
  }

  /**
   * Get the status line of the response.
   *@return StatusLine
   */
  public StatusLine getStatusLine() {
    return statusLine;
  }

  /** Get the staus code (conveniance function).
   *@return the status code of the status line.
   */
  public int getStatusCode() {
    return statusLine.getStatusCode();
  }

  /** Set the reason phrase.
   *@param reasonPhrase the reason phrase.
   *@throws IllegalArgumentException if null string
   */
  public void setReasonPhrase(String reasonPhrase) {
    if (reasonPhrase == null)
      throw new IllegalArgumentException("Bad reason phrase");
    if (this.statusLine == null)
      this.statusLine = new StatusLine();
    this.statusLine.setReasonPhrase(reasonPhrase);
  }

  /** Get the reason phrase.
   *@return the reason phrase.
   */
  public String getReasonPhrase() {
    if (statusLine == null || statusLine.getReasonPhrase() == null)
      return "";
    else
      return statusLine.getReasonPhrase();
  }

  /** Return true if the response is a final response.
   *@param rc is the return code.
   *@return true if the parameter is between the range 200 and 700.
   */
  public static boolean isFinalResponse(int rc) {
    return rc >= 200 && rc < 700;
  }

  /** Is this a final response?
   *@return true if this is a final response.
   */
  public boolean isFinalResponse() {
    return isFinalResponse(statusLine.getStatusCode());
  }

  /**
   * Set the status line field.
   *@param sl Status line to set.
   */
  public void setStatusLine(StatusLine sl) {
    statusLine = sl;
  }

  /** Constructor.
   */
  public SIPResponse() {
    super();
  }
  /**
   * Print formatting function.
   *Indent and parenthesize for pretty printing.
   * Note -- use the encode method for formatting the message.
   * Hack here to XMLize.
   *
   *@return a string for pretty printing.
   */
  public String debugDump() {
    String superstring = super.debugDump();
    stringRepresentation = "";
    sprint(SIPResponse.class.getCanonicalName());
    sprint("{");
    if (statusLine != null) {
      sprint(statusLine.debugDump());
    }
    sprint(superstring);
    sprint("}");
    return stringRepresentation;
  }

  /**
   * Check the response structure. Must have from, to CSEQ and VIA
   * headers.
   */
  public void checkHeaders() throws ParseException {
    if (getCSeq() == null) {
      throw new ParseException(CSeq.NAME+ " Is missing ", 0);
    }
    if (getTo() == null) {
      throw new ParseException(To.NAME+ " Is missing ", 0);
    }
    if (getFrom() == null) {
      throw new ParseException(From.NAME+ " Is missing ", 0);
    }
    if (getViaHeaders() == null) {
      throw new ParseException(Via.NAME+ " Is missing ", 0);
    }
    if (getCallId() == null) {
      throw new ParseException(CallID.NAME + " Is missing ", 0);
    }
   
   
    if (getStatusCode() > 699) {
      throw new ParseException("Unknown error code!" + getStatusCode(), 0);
    }

  }

  /**
   *  Encode the SIP Request as a string.
   *@return The string encoded canonical form of the message.
   */

  public String encode() {
    String retval;
    if (statusLine != null)
      retval = statusLine.encode() + super.encode();
    else
      retval = super.encode();
    return retval ;
  }

  /** Encode the message except for the body.
  *
  *@return The string except for the body.
  */

  public String encodeMessage() {
    String retval;
    if (statusLine != null)
      retval = statusLine.encode() + super.encodeSIPHeaders();
    else
      retval = super.encodeSIPHeaders();
    return retval ;
  }

   

  /** Get this message as a list of encoded strings.
   *@return LinkedList containing encoded strings for each header in
   *   the message.
   */

  public LinkedList getMessageAsEncodedStrings() {
    LinkedList retval = super.getMessageAsEncodedStrings();

    if (statusLine != null)
      retval.addFirst(statusLine.encode());
    return retval;

  }

  /**
   * Make a clone (deep copy) of this object.
   *@return a deep copy of this object.
   */

  public Object clone() {
    SIPResponse retval = (SIPResponse) super.clone();
    if (this.statusLine != null)
      retval.statusLine = (StatusLine) this.statusLine.clone();
    return retval;
  }
 

  /**
   * Compare for equality.
   *@param other other object to compare with.
   */
  public boolean equals(Object other) {
    if (!this.getClass().equals(other.getClass()))
      return false;
    SIPResponse that = (SIPResponse) other;
    return statusLine.equals(that.statusLine) && super.equals(other);
  }

  /**
   * Match with a template.
   *@param matchObj template object to match ourselves with (null
   * in any position in the template object matches wildcard)
   */
  public boolean match(Object matchObj) {
    if (matchObj == null)
      return true;
    else if (!matchObj.getClass().equals(this.getClass())) {
      return false;
    } else if (matchObj == this)
      return true;
    SIPResponse that = (SIPResponse) matchObj;
   
    StatusLine rline = that.statusLine;
    if (this.statusLine == null && rline != null)
      return false;
    else if (this.statusLine == rline)
      return super.match(matchObj);
    else {
     
      return statusLine.match(that.statusLine) && super.match(matchObj);
    }

  }

  /** Encode this into a byte array.
   * This is used when the body has been set as a binary array
   * and you want to encode the body as a byte array for transmission.
   *
   *@return a byte array containing the SIPRequest encoded as a byte
   *  array.
   */

  public byte[] encodeAsBytes( String transport ) {
    byte[] slbytes = null;
    if (statusLine != null) {
      try {
        slbytes = statusLine.encode().getBytes("UTF-8");
      } catch (UnsupportedEncodingException ex) {
        InternalErrorHandler.handleException(ex);
      }
    }
    byte[] superbytes = super.encodeAsBytes( transport );
    byte[] retval = new byte[slbytes.length + superbytes.length];
    System.arraycopy(slbytes, 0, retval, 0, slbytes.length);
    System.arraycopy(superbytes, 0, retval, slbytes.length,
        superbytes.length);
    return retval;
  }

 

  /** Get a dialog identifier.
   * Generates a string that can be used as a dialog identifier.
   *
   * @param isServer is set to true if this is the UAS
   * and set to false if this is the UAC
   */
  public String getDialogId(boolean isServer) {
    CallID cid = (CallID) this.getCallId();
    From from = (From) this.getFrom();
    To to = (To) this.getTo();
    StringBuffer retval = new StringBuffer(cid.getCallId());
    if (!isServer) {
      //retval.append(COLON).append(from.getUserAtHostPort());
      if (from.getTag() != null) {
        retval.append(COLON);
        retval.append(from.getTag());
      }
      //retval.append(COLON).append(to.getUserAtHostPort());
      if (to.getTag() != null) {
        retval.append(COLON);
        retval.append(to.getTag());
      }
    } else {
      //retval.append(COLON).append(to.getUserAtHostPort());
      if (to.getTag() != null) {
        retval.append(COLON);
        retval.append(to.getTag());
      }
      //retval.append(COLON).append(from.getUserAtHostPort());
      if (from.getTag() != null) {
        retval.append(COLON);
        retval.append(from.getTag());
      }
    }
    return retval.toString().toLowerCase();
  }

  public String getDialogId(boolean isServer, String toTag) {
    CallID cid = (CallID) this.getCallId();
    From from = (From) this.getFrom();
    StringBuffer retval = new StringBuffer(cid.getCallId());
    if (!isServer) {
      //retval.append(COLON).append(from.getUserAtHostPort());
      if (from.getTag() != null) {
        retval.append(COLON);
        retval.append(from.getTag());
      }
      //retval.append(COLON).append(to.getUserAtHostPort());
      if (toTag != null) {
        retval.append(COLON);
        retval.append(toTag);
      }
    } else {
      //retval.append(COLON).append(to.getUserAtHostPort());
      if (toTag != null) {
        retval.append(COLON);
        retval.append(toTag);
      }
      //retval.append(COLON).append(from.getUserAtHostPort());
      if (from.getTag() != null) {
        retval.append(COLON);
        retval.append(from.getTag());
      }
    }
    return retval.toString().toLowerCase();
  }

  /**
   * Sets the Via branch for CANCEL or ACK requests
   *
   * @param via
   * @param method
   * @throws ParseException
   */
  private final void setBranch( Via via, String method ) {
    String branch;
    if (method.equals( Request.ACK ) ) {
      if (statusLine.getStatusCode() >= 300 ) {
        branch = getTopmostVia().getBranch()// non-2xx ACK uses same branch
      } else {
        branch = Utils.getInstance().generateBranchId()// 2xx ACK gets new branch
      }
    } else if (method.equals( Request.CANCEL )) {
      branch = getTopmostVia().getBranch()// CANCEL uses same branch
    } else return;
   
    try {
      via.setBranch( branch );
    } catch (ParseException e) {
      e.printStackTrace();
    }
  }
 
 
  /**
   * Get the encoded first line.
   *
   *@return the status line encoded.
   *
   */
  public String getFirstLine() {
    if (this.statusLine == null)
      return null;
    else
      return this.statusLine.encode();
  }

  public void setSIPVersion(String sipVersion) {
    this.statusLine.setSipVersion(sipVersion);
  }

  public String getSIPVersion() {
    return this.statusLine.getSipVersion();
  }

  public String toString() {
    if (statusLine == null) return  "";
    else return statusLine.encode() + super.encode();
  }

    /**
     * Generate a request from a response.
     *
     * @param requestURI -- the request URI to assign to the request.
     * @param via -- the Via header to assign to the request
     * @param cseq -- the CSeq header to assign to the request
     * @param from -- the From header to assign to the request
     * @param to -- the To header to assign to the request
     * @return -- the newly generated sip request.
     */
    public SIPRequest createRequest(SipUri requestURI, Via via, CSeq cseq, From from, To to) {
      SIPRequest newRequest = new SIPRequest();
    String method = cseq.getMethod();
   
    newRequest.setMethod(method);
    newRequest.setRequestURI(requestURI);
    this.setBranch( via, method );
    newRequest.setHeader(via);
    newRequest.setHeader(cseq);
    Iterator headerIterator = getHeaders();
    while (headerIterator.hasNext()) {
      SIPHeader nextHeader = (SIPHeader) headerIterator.next();
      // Some headers do not belong in a Request ....
      if (SIPMessage.isResponseHeader(nextHeader)
        || nextHeader instanceof ViaList
        || nextHeader instanceof CSeq
        || nextHeader instanceof ContentType
        || nextHeader instanceof ContentLength
        || nextHeader instanceof RecordRouteList
        || nextHeader instanceof RequireList
        || nextHeader instanceof ContactList  // JvB: added
        || nextHeader instanceof ContentLength
        || nextHeader instanceof ServerHeader
        || nextHeader instanceof ReasonHeader
        || nextHeader instanceof ReasonList) {
        continue;
      }
      if (nextHeader instanceof To)
        nextHeader = (SIPHeader) to;
      else if (nextHeader instanceof From)
        nextHeader = (SIPHeader) from;
      try {
        newRequest.attachHeader(nextHeader, false);
      } catch (SIPDuplicateHeaderException e) {
          //Should not happen!
        e.printStackTrace();
      }
    }
   
    try {
      // JvB: all requests need a Max-Forwards
      newRequest.attachHeader( new MaxForwards(70), false);
    } catch (Exception d) {
     
    }
   
    if (MessageFactoryImpl.getDefaultUserAgentHeader() != null ) {
        newRequest.setHeader(MessageFactoryImpl.getDefaultUserAgentHeader())
    }
    return newRequest;
       
    }
}
TOP

Related Classes of gov.nist.javax.sip.message.SIPResponse

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.