0001: /*
0002: * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights
0003: * Reserved. Use is subject to license terms.
0004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0005: *
0006: * This program is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU General Public License version
0008: * 2 only, as published by the Free Software Foundation.
0009: *
0010: * This program is distributed in the hope that it will be useful, but
0011: * WITHOUT ANY WARRANTY; without even the implied warranty of
0012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0013: * General Public License version 2 for more details (a copy is
0014: * included at /legal/license.txt).
0015: *
0016: * You should have received a copy of the GNU General Public License
0017: * version 2 along with this work; if not, write to the Free Software
0018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0019: * 02110-1301 USA
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0022: * Clara, CA 95054 or visit www.sun.com if you need additional
0023: * information or have any questions.
0024: */
0025: /*
0026: */
0027: package gov.nist.siplite.message;
0028:
0029: import java.util.Enumeration;
0030: import java.io.UnsupportedEncodingException;
0031: import javax.microedition.sip.SipException;
0032:
0033: import gov.nist.siplite.address.*;
0034: import gov.nist.core.*;
0035: import gov.nist.siplite.header.*;
0036:
0037: /**
0038: * SIP Response structure.
0039: *
0040: * @version JAIN-SIP-1.1
0041: *
0042: *
0043: *<a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
0044: *
0045: */
0046: public final class Response extends Message {
0047: /** The current status line. */
0048: protected StatusLine statusLine;
0049:
0050: /**
0051: * This response indicates that the request has been received by the
0052: * next-hop server and that some unspecified action is being taken on
0053: * behalf of this call (for example, a database is being consulted). This
0054: * response, like all other provisional responses, stops retransmissions of
0055: * an INVITE by a UAC. The 100 (Trying) response is different from other
0056: * provisional responses, in that it is never forwarded upstream by a
0057: * stateful proxy.
0058: */
0059: public static final int TRYING = 100;
0060:
0061: /**
0062: * The User Agent receiving the INVITE is trying to alert the user. This
0063: * response MAY be used to initiate local ringback.
0064: */
0065: public static final int RINGING = 180;
0066:
0067: /**
0068: * A server MAY use this status code to indicate that the call is being
0069: * forwarded to a different set of destinations.
0070: */
0071: public static final int CALL_IS_BEING_FORWARDED = 181;
0072:
0073: /**
0074: * The called party is temporarily unavailable, but the server has decided
0075: * to queue the call rather than reject it. When the callee becomes
0076: * available, it will return the appropriate final status response. The
0077: * reason phrase MAY give further details about the status of the call,
0078: * for example, "5 calls queued; expected waiting time is 15 minutes". The
0079: * server MAY issue several 182 (Queued) responses to update the caller
0080: * about the status of the queued call.
0081: */
0082: public static final int QUEUED = 182;
0083:
0084: /**
0085: * The 183 (Session Progress) response is used to convey information about
0086: * the progress of the call that is not otherwise classified. The
0087: * Reason-Phrase, header fields, or message body MAY be used to convey more
0088: * details about the call progress.
0089: *
0090: * @since v1.1
0091: */
0092: public static final int SESSION_PROGRESS = 183;
0093:
0094: /**
0095: * The request has succeeded. The information returned with the response
0096: * depends on the method used in the request.
0097: */
0098: public static final int OK = 200;
0099:
0100: /**
0101: * The Acceptable extension response code signifies that the request has
0102: * been accepted for processing, but the processing has not been completed.
0103: * The request might or might not eventually be acted upon, as it might be
0104: * disallowed when processing actually takes place. There is no facility
0105: * for re-sending a status code from an asynchronous operation such as this.
0106: * The 202 response is intentionally non-committal. Its purpose is to allow
0107: * a server to accept a request for some other process (perhaps a
0108: * batch-oriented process that is only run once per day) without requiring
0109: * that the user agent's connection to the server persist until the process
0110: * is completed. The entity returned with this response SHOULD include an
0111: * indication of the request's current status and either a pointer to a
0112: * status monitor or some estimate of when the user can expect the request
0113: * to be fulfilled. This response code is specific to the event
0114: * notification framework.
0115: *
0116: * @since v1.1
0117: */
0118: public static final int ACCEPTED = 202;
0119:
0120: /**
0121: * The address in the request resolved to several choices, each with its
0122: * own specific location, and the user (or UA) can select a preferred
0123: * communication end point and redirect its request to that location.
0124: * <p>
0125: * The response MAY include a message body containing a list of resource
0126: * characteristics and location(s) from which the user or UA can choose
0127: * the one most appropriate, if allowed by the Accept request header field.
0128: * However, no MIME types have been defined for this message body.
0129: * <p>
0130: * The choices SHOULD also be listed as Contact fields. Unlike HTTP, the
0131: * SIP response MAY contain several Contact fields or a list of addresses
0132: * in a Contact field. User Agents MAY use the Contact header field value
0133: * for automatic redirection or MAY ask the user to confirm a choice.
0134: * However, this specification does not define any standard for such
0135: * automatic selection.
0136: * <p>
0137: * This status response is appropriate if the callee can be reached at
0138: * several different locations and the server cannot or prefers not to
0139: * proxy the request.
0140: */
0141: public static final int MULTIPLE_CHOICES = 300;
0142:
0143: /**
0144: * The user can no longer be found at the address in the Request-URI, and
0145: * the requesting client SHOULD retry at the new address given by the
0146: * Contact header field. The requestor SHOULD update any local directories,
0147: * address books, and user location caches with this new value and redirect
0148: * future requests to the address(es) listed.
0149: */
0150: public static final int MOVED_PERMANENTLY = 301;
0151:
0152: /**
0153: * The requesting client SHOULD retry the request at the new address(es)
0154: * given by the Contact header field. The Request-URI of the new request
0155: * uses the value of the Contact header field in the response.
0156: * <p>
0157: * The duration of the validity of the Contact URI can be indicated through
0158: * an Expires header field or an expires parameter in the Contact header
0159: * field. Both proxies and User Agents MAY cache this URI for the duration
0160: * of the expiration time. If there is no explicit expiration time, the
0161: * address is only valid once for recursing, and MUST NOT be cached for
0162: * future transactions.
0163: * <p>
0164: * If the URI cached from the Contact header field fails, the Request-URI
0165: * from the redirected request MAY be tried again a single time. The
0166: * temporary URI may have become out-of-date sooner than the expiration
0167: * time, and a new temporary URI may be available.
0168: */
0169: public static final int MOVED_TEMPORARILY = 302;
0170:
0171: /**
0172: * The requested resource MUST be accessed through the proxy given by the
0173: * Contact field. The Contact field gives the URI of the proxy. The
0174: * recipient is expected to repeat this single request via the proxy.
0175: * 305 (Use Proxy) responses MUST only be generated by UASs.
0176: */
0177: public static final int USE_PROXY = 305;
0178:
0179: /**
0180: * The call was not successful, but alternative services are possible. The
0181: * alternative services are described in the message body of the response.
0182: * Formats for such bodies are not defined here, and may be the subject of
0183: * future standardization.
0184: */
0185: public static final int ALTERNATIVE_SERVICE = 380;
0186:
0187: /**
0188: * The request could not be understood due to malformed syntax. The
0189: * Reason-Phrase SHOULD identify the syntax problem in more detail, for
0190: * example, "Missing Call-ID header field".
0191: */
0192: public static final int BAD_REQUEST = 400;
0193:
0194: /**
0195: * The request requires user authentication. This response is issued by
0196: * UASs and registrars, while 407 (Proxy Authentication Required) is used
0197: * by proxy servers.
0198: */
0199: public static final int UNAUTHORIZED = 401;
0200:
0201: /**
0202: * Reserved for future use.
0203: */
0204: public static final int PAYMENT_REQUIRED = 402;
0205:
0206: /**
0207: * The server understood the request, but is refusing to fulfill it.
0208: * Authorization will not help, and the request SHOULD NOT be repeated.
0209: */
0210: public static final int FORBIDDEN = 403;
0211:
0212: /**
0213: * The server has definitive information that the user does not exist at
0214: * the domain specified in the Request-URI. This status is also returned
0215: * if the domain in the Request-URI does not match any of the domains
0216: * handled by the recipient of the request.
0217: */
0218: public static final int NOT_FOUND = 404;
0219:
0220: /**
0221: * The method specified in the Request-Line is understood, but not allowed
0222: * for the address identified by the Request-URI. The response MUST include
0223: * an Allow header field containing a list of valid methods for the
0224: * indicated address
0225: */
0226: public static final int METHOD_NOT_ALLOWED = 405;
0227:
0228: /**
0229: * The resource identified by the request is only capable of generating
0230: * response entities that have content characteristics not acceptable
0231: * according to the Accept header field sent in the request.
0232: */
0233: public static final int NOT_ACCEPTABLE = 406;
0234:
0235: /**
0236: * This code is similar to 401 (Unauthorized), but indicates that
0237: * the client
0238: * MUST first authenticate itself with the proxy. This status code can be
0239: * used for applications where access to the communication channel (for
0240: * example, a telephony gateway) rather than the callee requires
0241: * authentication.
0242: */
0243: public static final int PROXY_AUTHENTICATION_REQUIRED = 407;
0244:
0245: /**
0246: * The server could not produce a response within a suitable amount of
0247: * time, for example, if it could not determine the location of the user
0248: * in time. The client MAY repeat the request without modifications at
0249: * any later time.
0250: */
0251: public static final int REQUEST_TIMEOUT = 408;
0252:
0253: /**
0254: * The requested resource is no longer available at the server and no
0255: * forwarding address is known. This condition is expected to be considered
0256: * permanent. If the server does not know, or has no facility to determine,
0257: * whether or not the condition is permanent, the status code 404
0258: * (Not Found) SHOULD be used instead.
0259: */
0260: public static final int GONE = 410;
0261:
0262: /**
0263: * The server is refusing to process a request because the request
0264: * entity-body is larger than the server is willing or able to process. The
0265: * server MAY close the connection to prevent the client from continuing
0266: * the request. If the condition is temporary, the server SHOULD include a
0267: * Retry-After header field to indicate that it is temporary and after what
0268: * time the client MAY try again.
0269: *
0270: * @since v1.1
0271: */
0272: public static final int REQUEST_ENTITY_TOO_LARGE = 413;
0273:
0274: /**
0275: * The server is refusing to service the request because the Request-URI
0276: * is longer than the server is willing to interpret.
0277: *
0278: * @since v1.1
0279: */
0280: public static final int REQUEST_URI_TOO_LONG = 414;
0281:
0282: /**
0283: * The server is refusing to service the request because the message body
0284: * of the request is in a format not supported by the server for the
0285: * requested method. The server MUST return a list of acceptable formats
0286: * using the Accept, Accept-Encoding, or Accept-Language header field,
0287: * depending on the specific problem with the content.
0288: */
0289: public static final int UNSUPPORTED_MEDIA_TYPE = 415;
0290:
0291: /**
0292: * The server cannot process the request because the scheme of the URI in
0293: * the Request-URI is unknown to the server.
0294: *
0295: * @since v1.1
0296: */
0297: public static final int UNSUPPORTED_URI_SCHEME = 416;
0298:
0299: /**
0300: * The server did not understand the protocol extension specified in a
0301: * Proxy-Require or Require header field. The server MUST include a list of
0302: * the unsupported extensions in an Unsupported header field in
0303: * the response.
0304: */
0305: public static final int BAD_EXTENSION = 420;
0306:
0307: /**
0308: * The UAS needs a particular extension to process the request, but this
0309: * extension is not listed in a Supported header field in the request.
0310: * Responses with this status code MUST contain a Require header field
0311: * listing the required extensions.
0312: * <p>
0313: * A UAS SHOULD NOT use this response unless it truly cannot provide any
0314: * useful service to the client. Instead, if a desirable extension is not
0315: * listed in the Supported header field, servers SHOULD process the request
0316: * using baseline SIP capabilities and any extensions supported by the
0317: * client.
0318: *
0319: * @since v1.1
0320: */
0321: public static final int EXTENSION_REQUIRED = 421;
0322:
0323: /**
0324: * The server is rejecting the request because the expiration time of the
0325: * resource refreshed by the request is too short. This response can be
0326: * used by a registrar to reject a registration whose Contact header field
0327: * expiration time was too small.
0328: *
0329: * @since v1.1
0330: */
0331: public static final int INTERVAL_TOO_BRIEF = 423;
0332:
0333: /**
0334: * The callee's end system was contacted successfully but the callee is
0335: * currently unavailable (for example, is not logged in, logged in but in a
0336: * state that precludes communication with the callee, or has activated the
0337: * "do not disturb" feature). The response MAY indicate a better time to
0338: * call in the Retry-After header field. The user could also be available
0339: * elsewhere (unbeknownst to this server). The reason phrase
0340: * SHOULD indicate
0341: * a more precise cause as to why the callee is unavailable. This value
0342: * SHOULD be settable by the UA. Status 486 (Busy Here) MAY be used to more
0343: * precisely indicate a particular reason for the call failure.
0344: * <p>
0345: * This status is also returned by a redirect or proxy server that
0346: * recognizes the user identified by the Request-URI, but does not
0347: * currently have a valid forwarding location for that user.
0348: *
0349: * @since v1.1
0350: */
0351: public static final int TEMPORARILY_UNAVAILABLE = 480;
0352:
0353: /**
0354: * This status indicates that the UAS received a request that does not
0355: * match any existing dialog or transaction.
0356: */
0357: public static final int CALL_OR_TRANSACTION_DOES_NOT_EXIST = 481;
0358:
0359: /**
0360: * The server has detected a loop.
0361: */
0362: public static final int LOOP_DETECTED = 482;
0363:
0364: /**
0365: * The server received a request that contains a Max-Forwards header field
0366: * with the value zero.
0367: */
0368: public static final int TOO_MANY_HOPS = 483;
0369:
0370: /**
0371: * The server received a request with a Request-URI that was incomplete.
0372: * Additional information SHOULD be provided in the reason phrase. This
0373: * status code allows overlapped dialing. With overlapped dialing, the
0374: * client does not know the length of the dialing string. It sends strings
0375: * of increasing lengths, prompting the user for more input, until it no
0376: * longer receives a 484 (Address Incomplete) status response.
0377: */
0378: public static final int ADDRESS_INCOMPLETE = 484;
0379:
0380: /**
0381: * The Request-URI was ambiguous. The response MAY contain a listing of
0382: * possible unambiguous addresses in Contact header fields. Revealing
0383: * alternatives can infringe on privacy of the user or the organization.
0384: * It MUST be possible to configure a server to respond with status 404
0385: * (Not Found) or to suppress the listing of possible choices for ambiguous
0386: * Request-URIs. Some email and voice mail systems provide this
0387: * functionality. A status code separate from 3xx is used since the
0388: * semantics are different: for 300, it is assumed that the same person or
0389: * service will be reached by the choices provided. While an automated
0390: * choice or sequential search makes sense for a 3xx response, user
0391: * intervention is required for a 485 (Ambiguous) response.
0392: */
0393: public static final int AMBIGUOUS = 485;
0394:
0395: /**
0396: * The callee's end system was contacted successfully, but the callee is
0397: * currently not willing or able to take additional calls at this end
0398: * system. The response MAY indicate a better time to call in the
0399: * Retry-After
0400: * header field. The user could also be available elsewhere, such as
0401: * through a voice mail service. Status 600 (Busy Everywhere) SHOULD be
0402: * used if the client knows that no other end system will be able to accept
0403: * this call.
0404: */
0405: public static final int BUSY_HERE = 486;
0406:
0407: /**
0408: * The request was terminated by a BYE or CANCEL request. This response is
0409: * never returned for a CANCEL request itself.
0410: *
0411: * @since v1.1
0412: */
0413: public static final int REQUEST_TERMINATED = 487;
0414:
0415: /**
0416: * The response has the same meaning as 606 (Not Acceptable), but only
0417: * applies to the specific resource addressed by the Request-URI and the
0418: * request may succeed elsewhere. A message body containing a description
0419: * of media capabilities MAY be present in the response, which is formatted
0420: * according to the Accept header field in the INVITE (or application/sdp
0421: * if not present), the same as a message body in a 200 (OK) response to
0422: * an OPTIONS request.
0423: *
0424: * @since v1.1
0425: */
0426: public static final int NOT_ACCEPTABLE_HERE = 488;
0427:
0428: /**
0429: * The Bad Event extension response code is used to indicate that the
0430: * server did not understand the event package specified in a "Event"
0431: * header field. This response code is specific to the event notification
0432: * framework.
0433: *
0434: * @since v1.1
0435: */
0436: public static final int BAD_EVENT = 489;
0437:
0438: /**
0439: * The request was received by a UAS that had a pending request within
0440: * the same dialog.
0441: *
0442: * @since v1.1
0443: */
0444: public static final int REQUEST_PENDING = 491;
0445:
0446: /**
0447: * The request was received by a UAS that contained an encrypted MIME body
0448: * for which the recipient does not possess or will not provide an
0449: * appropriate decryption key. This response MAY have a single body
0450: * containing an appropriate public key that should be used to encrypt MIME
0451: * bodies sent to this UA.
0452: *
0453: * @since v1.1
0454: */
0455: public static final int UNDECIPHERABLE = 493;
0456:
0457: /**
0458: * The server encountered an unexpected condition that prevented it from
0459: * fulfilling the request. The client MAY display the specific error
0460: * condition and MAY retry the request after several seconds. If the
0461: * condition is temporary, the server MAY indicate when the client may
0462: * retry the request using the Retry-After header field.
0463: */
0464: public static final int SERVER_INTERNAL_ERROR = 500;
0465:
0466: /**
0467: * The server does not support the functionality required to fulfill the
0468: * request. This is the appropriate response when a UAS does not recognize
0469: * the request method and is not capable of supporting it for any user.
0470: * Proxies forward all requests regardless of method. Note that a 405
0471: * (Method Not Allowed) is sent when the server recognizes the request
0472: * method, but that method is not allowed or supported.
0473: */
0474: public static final int NOT_IMPLEMENTED = 501;
0475:
0476: /**
0477: * The server, while acting as a gateway or proxy, received an invalid
0478: * response from the downstream server it accessed in attempting to
0479: * fulfill the request.
0480: */
0481: public static final int BAD_GATEWAY = 502;
0482:
0483: /**
0484: * The server is temporarily unable to process the request due to a
0485: * temporary overloading or maintenance of the server. The server MAY
0486: * indicate when the client should retry the request in a Retry-After
0487: * header field. If no Retry-After is given, the client MUST act as if it
0488: * had received a 500 (Server Internal Error) response.
0489: * <p>
0490: * A client (proxy or UAC) receiving a 503 (Service Unavailable) SHOULD
0491: * attempt to forward the request to an alternate server. It SHOULD NOT
0492: * forward any other requests to that server for the duration specified
0493: * in the Retry-After header field, if present.
0494: * <p>
0495: * Servers MAY refuse the connection or drop the request instead of
0496: * responding with 503 (Service Unavailable).
0497: *
0498: * @since v1.1
0499: */
0500: public static final int SERVICE_UNAVAILABLE = 503;
0501:
0502: /**
0503: * The server did not receive a timely response from an external server
0504: * it accessed in attempting to process the request. 408 (Request Timeout)
0505: * should be used instead if there was no response within the
0506: * period specified in the Expires header field from the upstream server.
0507: */
0508: public static final int SERVER_TIMEOUT = 504;
0509:
0510: /**
0511: * The server does not support, or refuses to support, the SIP protocol
0512: * version that was used in the request. The server is indicating that
0513: * it is unable or unwilling to complete the request using the same major
0514: * version as the client, other than with this error message.
0515: */
0516: public static final int VERSION_NOT_SUPPORTED = 505;
0517:
0518: /**
0519: * The server was unable to process the request since the message length
0520: * exceeded its capabilities.
0521: *
0522: * @since v1.1
0523: */
0524: public static final int MESSAGE_TOO_LARGE = 513;
0525:
0526: /**
0527: * The callee's end system was contacted successfully but the callee is
0528: * busy and does not wish to take the call at this time. The response
0529: * MAY indicate a better time to call in the Retry-After header field.
0530: * If the callee does not wish to reveal the reason for declining the call,
0531: * the callee uses status code 603 (Decline) instead. This status response
0532: * is returned only if the client knows that no other end point (such as a
0533: * voice mail system) will answer the request. Otherwise, 486 (Busy Here)
0534: * should be returned.
0535: */
0536: public static final int BUSY_EVERYWHERE = 600;
0537:
0538: /**
0539: * The callee's machine was successfully contacted but the user explicitly
0540: * does not wish to or cannot participate. The response MAY indicate a
0541: * better time to call in the Retry-After header field. This status
0542: * response is returned only if the client knows that no other end point
0543: * will answer the request.
0544: */
0545: public static final int DECLINE = 603;
0546:
0547: /**
0548: * The server has authoritative information that the user indicated in the
0549: * Request-URI does not exist anywhere.
0550: */
0551: public static final int DOES_NOT_EXIST_ANYWHERE = 604;
0552:
0553: /**
0554: * The user's agent was contacted successfully but some aspects of the
0555: * session description such as the requested media, bandwidth, or
0556: * addressing
0557: * style were not acceptable. A 606 (Not Acceptable) response means that
0558: * the user wishes to communicate, but cannot adequately support the
0559: * session described. The 606 (Not Acceptable) response MAY contain a list
0560: * of reasons in a Warning header field describing why the session
0561: * described
0562: * cannot be supported.
0563: * <p>
0564: * A message body containing a description of media capabilities MAY be
0565: * present in the response, which is formatted according to the Accept
0566: * header field in the INVITE (or application/sdp if not present), the same
0567: * as a message body in a 200 (OK) response to an OPTIONS request.
0568: * <p>
0569: * It is hoped that negotiation will not frequently be needed, and when a
0570: * new user is being invited to join an already existing conference,
0571: * negotiation may not be possible. It is up to the invitation initiator to
0572: * decide whether or not to act on a 606 (Not Acceptable) response.
0573: * <p>
0574: * This status response is returned only if the client knows that no other
0575: * end point will answer the request. This specification renames this
0576: * status code from NOT_ACCEPTABLE as in RFC3261 to SESSION_NOT_ACCEPTABLE
0577: * due to it conflict with 406 (Not Acceptable) defined in this interface.
0578: */
0579: public static final int SESSION_NOT_ACCEPTABLE = 606;
0580:
0581: /**
0582: * Gets the reason phrase.
0583: * @param rc the reason code
0584: * @return the reason phrase as a string
0585: */
0586: public static String getReasonPhrase(int rc) {
0587: String retval = null;
0588:
0589: switch (rc) {
0590: case TRYING:
0591: retval = "Trying";
0592: break;
0593:
0594: case RINGING:
0595: retval = "Ringing";
0596: break;
0597:
0598: case CALL_IS_BEING_FORWARDED:
0599: retval = "Call is being forwarded";
0600: break;
0601:
0602: case QUEUED:
0603: retval = "Queued";
0604: break;
0605:
0606: case SESSION_PROGRESS:
0607: retval = "Session progress";
0608: break;
0609:
0610: case OK:
0611: retval = "OK";
0612: break;
0613:
0614: case ACCEPTED:
0615: retval = "Accepted";
0616: break;
0617:
0618: case MULTIPLE_CHOICES:
0619: retval = "Multiple choices";
0620: break;
0621:
0622: case MOVED_PERMANENTLY:
0623: retval = "Moved permanently";
0624: break;
0625:
0626: case MOVED_TEMPORARILY:
0627: retval = "Moved Temporarily";
0628: break;
0629:
0630: case USE_PROXY:
0631: retval = "Use proxy";
0632: break;
0633:
0634: case ALTERNATIVE_SERVICE:
0635: retval = "Alternative service";
0636: break;
0637:
0638: case BAD_REQUEST:
0639: retval = "Bad request";
0640: break;
0641:
0642: case UNAUTHORIZED:
0643: retval = "Unauthorized";
0644: break;
0645:
0646: case PAYMENT_REQUIRED:
0647: retval = "Payment required";
0648: break;
0649:
0650: case FORBIDDEN:
0651: retval = "Forbidden";
0652: break;
0653:
0654: case NOT_FOUND:
0655: retval = "Not found";
0656: break;
0657:
0658: case METHOD_NOT_ALLOWED:
0659: retval = "Method not allowed";
0660: break;
0661:
0662: case NOT_ACCEPTABLE:
0663: retval = "Not acceptable";
0664: break;
0665:
0666: case PROXY_AUTHENTICATION_REQUIRED:
0667: retval = "Proxy Authentication required";
0668: break;
0669:
0670: case REQUEST_TIMEOUT:
0671: retval = "Request timeout";
0672: break;
0673:
0674: case GONE:
0675: retval = "Gone";
0676: break;
0677:
0678: case TEMPORARILY_UNAVAILABLE:
0679: retval = "Temporarily Unavailable";
0680: break;
0681:
0682: case REQUEST_ENTITY_TOO_LARGE:
0683: retval = "Request entity too large";
0684: break;
0685:
0686: case REQUEST_URI_TOO_LONG:
0687: retval = "Request-URI too large";
0688: break;
0689:
0690: case UNSUPPORTED_MEDIA_TYPE:
0691: retval = "Unsupported media type";
0692: break;
0693:
0694: case UNSUPPORTED_URI_SCHEME:
0695: retval = "Unsupported URI Scheme";
0696: break;
0697:
0698: case BAD_EXTENSION:
0699: retval = "Bad extension";
0700: break;
0701:
0702: case EXTENSION_REQUIRED:
0703: retval = "Etension Required";
0704: break;
0705:
0706: case INTERVAL_TOO_BRIEF:
0707: retval = "Interval too brief";
0708: break;
0709:
0710: case CALL_OR_TRANSACTION_DOES_NOT_EXIST:
0711: retval = "Call leg/Transaction does not exist";
0712: break;
0713:
0714: case LOOP_DETECTED:
0715: retval = "Loop detected";
0716: break;
0717:
0718: case TOO_MANY_HOPS:
0719: retval = "Too many hops";
0720: break;
0721:
0722: case ADDRESS_INCOMPLETE:
0723: retval = "Address incomplete";
0724: break;
0725:
0726: case AMBIGUOUS:
0727: retval = "Ambiguous";
0728: break;
0729:
0730: case BUSY_HERE:
0731: retval = "Busy here";
0732: break;
0733:
0734: case REQUEST_TERMINATED:
0735: retval = "Request Terminated";
0736: break;
0737:
0738: case NOT_ACCEPTABLE_HERE:
0739: retval = "Not Accpetable here";
0740: break;
0741:
0742: case BAD_EVENT:
0743: retval = "Bad Event";
0744: break;
0745:
0746: case REQUEST_PENDING:
0747: retval = "Request Pending";
0748: break;
0749:
0750: case SERVER_INTERNAL_ERROR:
0751: retval = "Server Internal Error";
0752: break;
0753:
0754: case UNDECIPHERABLE:
0755: retval = "Undecipherable";
0756: break;
0757:
0758: case NOT_IMPLEMENTED:
0759: retval = "Not implemented";
0760: break;
0761:
0762: case BAD_GATEWAY:
0763: retval = "Bad gateway";
0764: break;
0765:
0766: case SERVICE_UNAVAILABLE:
0767: retval = "Service unavailable";
0768: break;
0769:
0770: case SERVER_TIMEOUT:
0771: retval = "Gateway timeout";
0772: break;
0773:
0774: case VERSION_NOT_SUPPORTED:
0775: retval = "SIP version not supported";
0776: break;
0777:
0778: case MESSAGE_TOO_LARGE:
0779: retval = "Message Too Large";
0780: break;
0781:
0782: case BUSY_EVERYWHERE:
0783: retval = "Busy everywhere";
0784: break;
0785:
0786: case DECLINE:
0787: retval = "Decline";
0788: break;
0789:
0790: case DOES_NOT_EXIST_ANYWHERE:
0791: retval = "Does not exist anywhere";
0792: break;
0793:
0794: case SESSION_NOT_ACCEPTABLE:
0795: retval = "Session Not acceptable";
0796: break;
0797:
0798: default: {
0799: // null value may cause an exception in setReasonPhrase()
0800: retval = "";
0801: }
0802: }
0803:
0804: return retval;
0805: }
0806:
0807: /**
0808: * set the status code.
0809: * @param statusCode is the status code to set.
0810: * @throws IllegalArgumentException if invalid status code.
0811: */
0812: public void setStatusCode(int statusCode) throws ParseException {
0813: if (statusCode < 100 || statusCode > 800) {
0814: throw new ParseException("bad status code", 0);
0815: }
0816:
0817: if (statusLine == null) {
0818: statusLine = new StatusLine();
0819: }
0820: statusLine.setStatusCode(statusCode);
0821: }
0822:
0823: /**
0824: * Get the status line of the response.
0825: * @return StatusLine
0826: */
0827: public StatusLine getStatusLine() {
0828: return statusLine;
0829: }
0830:
0831: /**
0832: * Get the staus code (conveniance function).
0833: * @return the status code of the status line.
0834: */
0835: public int getStatusCode() {
0836: return statusLine.getStatusCode();
0837: }
0838:
0839: /**
0840: * Set the reason phrase.
0841: * @param reasonPhrase the reason phrase.
0842: * @throws IllegalArgumentException if null string
0843: */
0844: public void setReasonPhrase(String reasonPhrase)
0845: throws IllegalArgumentException {
0846: if (reasonPhrase == null)
0847: throw new IllegalArgumentException("Bad reason phrase");
0848: if (this .statusLine == null)
0849: this .statusLine = new StatusLine();
0850: this .statusLine.setReasonPhrase(reasonPhrase);
0851: }
0852:
0853: /**
0854: * Get the reason phrase.
0855: * @return the reason phrase.
0856: */
0857: public String getReasonPhrase() {
0858: if (statusLine == null || statusLine.getReasonPhrase() == null)
0859: return "";
0860: else
0861: return statusLine.getReasonPhrase();
0862: }
0863:
0864: /**
0865: * Return true if the response is a final response.
0866: * @param rc is the return code.
0867: * @return true if the parameter is between the range 200 and 700.
0868: */
0869: public static boolean isFinalResponse(int rc) {
0870: return rc >= 200 && rc < 700;
0871: }
0872:
0873: /**
0874: * Is this a final response?
0875: * @return true if this is a final response.
0876: */
0877: public boolean isFinalResponse() {
0878: return isFinalResponse(statusLine.getStatusCode());
0879: }
0880:
0881: /**
0882: * Set the status line field.
0883: * @param sl Status line to set.
0884: */
0885: public void setStatusLine(StatusLine sl) {
0886: statusLine = sl;
0887: }
0888:
0889: /**
0890: * Constructor.
0891: */
0892: public Response() {
0893: super ();
0894: }
0895:
0896: /**
0897: * Check the response structure. Must have from, to CSEQ and VIA
0898: * headers.
0899: */
0900: protected void checkHeaders() throws ParseException {
0901: if (getCSeqHeader() == null) {
0902: throw new ParseException(Header.CSEQ, 0);
0903: }
0904: if (getTo() == null) {
0905: throw new ParseException(Header.TO, 0);
0906: }
0907: if (getFromHeader() == null) {
0908: throw new ParseException(Header.FROM, 0);
0909: }
0910: if (getViaHeaders() == null) {
0911: throw new ParseException(Header.VIA, 0);
0912: }
0913: }
0914:
0915: /**
0916: * Encode the SIP Request as a string.
0917: * @return The string encoded canonical form of the message.
0918: */
0919:
0920: public String encode() {
0921: String retval;
0922: if (statusLine != null)
0923: retval = statusLine.encode() + super .encode();
0924: else
0925: retval = super .encode();
0926: return retval;
0927: }
0928:
0929: /**
0930: * Make a clone (deep copy) of this object.
0931: * @return a deep copy of this object.
0932: */
0933:
0934: public Object clone() {
0935: Response retval = (Response) super .clone();
0936: retval.statusLine = (StatusLine) this .statusLine.clone();
0937: return retval;
0938: }
0939:
0940: /**
0941: * Compare for equality.
0942: * @param other other object to compare with.
0943: * @return true if the objects match
0944: */
0945: public boolean equals(Object other) {
0946: if (!this .getClass().equals(other.getClass()))
0947: return false;
0948: Response that = (Response) other;
0949: return statusLine.equals(that.statusLine)
0950: && super .equals(other);
0951: }
0952:
0953: /**
0954: * Encode this into a byte array.
0955: * This is used when the body has been set as a binary array
0956: * and you want to encode the body as a byte array for transmission.
0957: *
0958: * @return a byte array containing the Request encoded as a byte
0959: * array.
0960: */
0961: public byte[] encodeAsBytes() {
0962: byte[] slbytes = null;
0963: if (statusLine != null) {
0964: try {
0965: slbytes = statusLine.encode().getBytes("UTF-8");
0966: } catch (UnsupportedEncodingException ex) {
0967: InternalErrorHandler.handleException(ex);
0968: }
0969: }
0970: byte[] super bytes = super .encodeAsBytes();
0971: byte[] retval = new byte[slbytes.length + super bytes.length];
0972: int i = 0;
0973: if (slbytes != null) {
0974: for (i = 0; i < slbytes.length; i++) {
0975: retval[i] = slbytes[i];
0976: }
0977: }
0978:
0979: for (int j = 0; j < super bytes.length; j++, i++) {
0980: retval[i] = super bytes[j];
0981: }
0982: return retval;
0983: }
0984:
0985: /**
0986: * Create a new Request from the given response. Note that the
0987: * RecordRoute Via and CSeqHeader headers are not copied from the response.
0988: * These have to be added by the caller.
0989: * This method is useful for generating ACK messages from final
0990: * responses.
0991: *
0992: * @param requestURI is the request URI to use.
0993: * @param via is the via header to use.
0994: * @param cseq is the cseq header to use in the generated
0995: * request.
0996: * @return a new request obect.
0997: * @throws SipException if the request can't be created.
0998: */
0999: public Request createRequest(URI requestURI, ViaHeader via,
1000: CSeqHeader cseq) throws SipException {
1001: Request newRequest = new Request();
1002: String method = cseq.getMethod();
1003:
1004: newRequest.setMethod(method);
1005: newRequest.setRequestURI(requestURI);
1006:
1007: if ((equalsIgnoreCase(method, Request.ACK) || equalsIgnoreCase(
1008: method, Request.CANCEL))
1009: && this .getTopmostVia().getBranch() != null) {
1010: // Use the
1011: via.setBranch(this .getTopmostVia().getBranch());
1012: }
1013:
1014: newRequest.setHeader(via);
1015: newRequest.setHeader(cseq);
1016:
1017: Enumeration headerIterator = getHeaders();
1018: while (headerIterator.hasMoreElements()) {
1019: Header nextHeader = (Header) headerIterator.nextElement();
1020: // Some headers do not belong in a Request ....
1021: if (Message.isResponseHeader(nextHeader)
1022: || nextHeader instanceof ViaList
1023: || nextHeader instanceof CSeqHeader
1024: || nextHeader instanceof ContentTypeHeader
1025: || nextHeader instanceof RecordRouteList) {
1026: continue;
1027: }
1028: if (nextHeader instanceof ToHeader)
1029: nextHeader = (Header) nextHeader.clone();
1030: else if (nextHeader instanceof FromHeader)
1031: nextHeader = (Header) nextHeader.clone();
1032:
1033: newRequest.attachHeader(nextHeader, false);
1034: }
1035:
1036: return newRequest;
1037: }
1038:
1039: /**
1040: * Get the encoded first line.
1041: *
1042: * @return the status line encoded.
1043: *
1044: */
1045: public String getFirstLine() {
1046: if (this .statusLine == null)
1047: return null;
1048: else
1049: return this .statusLine.encode();
1050: }
1051:
1052: /**
1053: * Sets the SIP version string.
1054: * @param sipVersion the new SIP version
1055: */
1056: public void setSIPVersion(String sipVersion) {
1057: this .statusLine.setSipVersion(sipVersion);
1058: }
1059:
1060: /**
1061: * Gets the SIP version string.
1062: * @return the SIP version string
1063: */
1064: public String getSIPVersion() {
1065: return this .statusLine.getSipVersion();
1066: }
1067:
1068: /**
1069: * Encodes the object contents as a string
1070: * @return encoded string of object contents
1071: */
1072: public String toString() {
1073: return statusLine.encode() + super.encode();
1074: }
1075:
1076: }
|