Home | History | Annotate | Download | only in header
      1 /*
      2 * Conditions Of Use
      3 *
      4 * This software was developed by employees of the National Institute of
      5 * Standards and Technology (NIST), an agency of the Federal Government.
      6 * Pursuant to title 15 Untied States Code Section 105, works of NIST
      7 * employees are not subject to copyright protection in the United States
      8 * and are considered to be in the public domain.  As a result, a formal
      9 * license is not needed to use the software.
     10 *
     11 * This software is provided by NIST as a service and is expressly
     12 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
     13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
     14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
     15 * AND DATA ACCURACY.  NIST does not warrant or make any representations
     16 * regarding the use of the software or the results thereof, including but
     17 * not limited to the correctness, accuracy, reliability or usefulness of
     18 * the software.
     19 *
     20 * Permission to use this software is contingent upon your acceptance
     21 * of the terms of this agreement
     22 *
     23 * .
     24 *
     25 */
     26 /*******************************************************************************
     27 * Product of NIST/ITL Advanced Networking Technologies Division (ANTD).        *
     28 *******************************************************************************/
     29 package gov.nist.javax.sip.header;
     30 
     31 import gov.nist.core.Host;
     32 import gov.nist.core.HostPort;
     33 import gov.nist.core.NameValue;
     34 import gov.nist.core.NameValueList;
     35 import gov.nist.javax.sip.stack.HopImpl;
     36 
     37 import javax.sip.InvalidArgumentException;
     38 import javax.sip.address.Hop;
     39 import javax.sip.header.ViaHeader;
     40 import java.text.ParseException;
     41 
     42 /**
     43  * Via SIPHeader (these are strung together in a ViaList).
     44  *
     45  * @see ViaList
     46  *
     47  * @version 1.2 $Revision: 1.17 $ $Date: 2009/10/18 13:46:33 $
     48  *
     49  * @author M. Ranganathan   <br/>
     50  *
     51  *
     52  *
     53  */
     54 public class Via
     55     extends ParametersHeader
     56     implements javax.sip.header.ViaHeader, ViaHeaderExt {
     57 
     58     /**
     59      * Comment for <code>serialVersionUID</code>
     60      */
     61     private static final long serialVersionUID = 5281728373401351378L;
     62 
     63     /** The branch parameter is included by every forking proxy.
     64     */
     65     public static final String BRANCH = ParameterNames.BRANCH;
     66 
     67     /** The "received" parameter is added only for receiver-added Via Fields.
     68      */
     69     public static final String RECEIVED = ParameterNames.RECEIVED;
     70 
     71     /** The "maddr" paramter is designating the multicast address.
     72      */
     73     public static final String MADDR = ParameterNames.MADDR;
     74 
     75     /** The "TTL" parameter is designating the time-to-live value.
     76      */
     77     public static final String TTL = ParameterNames.TTL;
     78 
     79     /** The RPORT parameter.
     80     */
     81     public static final String RPORT = ParameterNames.RPORT;
     82 
     83     /** sentProtocol field.
     84      */
     85     protected Protocol sentProtocol;
     86 
     87     /** sentBy field.
     88      */
     89     protected HostPort sentBy;
     90 
     91     /**
     92      * comment field
     93      *
     94      * JvB note: RFC3261 does not allow a comment to appear in Via headers, and this
     95      * is not accessible through the API. Suggest removal
     96      */
     97     protected String comment;
     98 
     99     private boolean rPortFlag = false;
    100 
    101     /** Default constructor
    102     */
    103     public Via() {
    104         super(NAME);
    105         sentProtocol = new Protocol();
    106     }
    107 
    108     public boolean equals(Object other) {
    109 
    110         if (other==this) return true;
    111 
    112         if (other instanceof ViaHeader) {
    113             final ViaHeader o = (ViaHeader) other;
    114             return getProtocol().equalsIgnoreCase( o.getProtocol() )
    115                 && getTransport().equalsIgnoreCase( o.getTransport() )
    116                 && getHost().equalsIgnoreCase( o.getHost() )
    117                 && getPort() == o.getPort()
    118                 && equalParameters( o );
    119         }
    120         return false;
    121     }
    122 
    123 
    124     /** get the Protocol Version
    125      * @return String
    126      */
    127     public String getProtocolVersion() {
    128         if (sentProtocol == null)
    129             return null;
    130         else
    131             return sentProtocol.getProtocolVersion();
    132     }
    133 
    134     /**
    135      * Accessor for the sentProtocol field.
    136      * @return Protocol field
    137      */
    138     public Protocol getSentProtocol() {
    139 
    140         return sentProtocol;
    141     }
    142 
    143     /**
    144      * Accessor for the sentBy field
    145      *@return SentBy field
    146      */
    147     public HostPort getSentBy() {
    148         return sentBy;
    149     }
    150 
    151     /**
    152      * Get the host, port and transport as a Hop. This is
    153      * useful for the stack to avoid duplication of code.
    154      *
    155      */
    156     public Hop getHop() {
    157         HopImpl hop = new HopImpl(sentBy.getHost().getHostname(),
    158                 sentBy.getPort(),sentProtocol.getTransport());
    159         return hop;
    160     }
    161 
    162     /**
    163      * Accessor for the parameters field
    164      * @return parameters field
    165      */
    166     public NameValueList getViaParms() {
    167         return parameters;
    168     }
    169 
    170     /**
    171      * Accessor for the comment field.
    172      * @return comment field.
    173      * @deprecated RFC 2543 support feature.
    174      */
    175     public String getComment() {
    176         return comment;
    177     }
    178 
    179 
    180 
    181     /** port of the Via Header.
    182      * @return true if Port exists.
    183      */
    184     public boolean hasPort() {
    185         return (getSentBy()).hasPort();
    186     }
    187 
    188     /** comment of the Via Header.
    189      *
    190      * @return false if comment does not exist and true otherwise.
    191      */
    192     public boolean hasComment() {
    193         return comment != null;
    194     }
    195 
    196     /** remove the port.
    197      */
    198     public void removePort() {
    199         sentBy.removePort();
    200     }
    201 
    202     /** remove the comment field.
    203      */
    204     public void removeComment() {
    205         comment = null;
    206     }
    207 
    208     /** set the Protocol Version
    209      * @param protocolVersion String to set
    210      */
    211     public void setProtocolVersion(String protocolVersion) {
    212         if (sentProtocol == null)
    213             sentProtocol = new Protocol();
    214         sentProtocol.setProtocolVersion(protocolVersion);
    215     }
    216 
    217     /** set the Host of the Via Header
    218          * @param host String to set
    219          */
    220     public void setHost(Host host) {
    221         if (sentBy == null) {
    222             sentBy = new HostPort();
    223         }
    224         sentBy.setHost(host);
    225     }
    226 
    227     /**
    228      * Set the sentProtocol member
    229      * @param s Protocol to set.
    230      */
    231     public void setSentProtocol(Protocol s) {
    232         sentProtocol = s;
    233     }
    234 
    235     /**
    236      * Set the sentBy member
    237      * @param s HostPort to set.
    238      */
    239     public void setSentBy(HostPort s) {
    240         sentBy = s;
    241     }
    242 
    243     /**
    244      * Set the comment member
    245      * @param c String to set.
    246      * @deprecated This is an RFC 2543 feature.
    247      */
    248     public void setComment(String c) {
    249         comment = c;
    250     }
    251 
    252     /** Encode the body of this header (the stuff that follows headerName).
    253      * A.K.A headerValue.
    254      */
    255     protected String encodeBody() {
    256         return encodeBody(new StringBuffer()).toString();
    257     }
    258 
    259     protected StringBuffer encodeBody(StringBuffer buffer) {
    260         sentProtocol.encode(buffer);
    261         buffer.append(SP);
    262         sentBy.encode(buffer);
    263         if (!parameters.isEmpty()) {
    264             buffer.append(SEMICOLON);
    265             parameters.encode(buffer);
    266         }
    267         if (comment != null) {
    268             buffer.append(SP).append(LPAREN).append(comment).append(RPAREN);
    269         }
    270         if (rPortFlag) buffer.append(";rport");
    271         return buffer;
    272     }
    273 
    274     /**
    275      * Set the host part of this ViaHeader to the newly supplied <code>host</code>
    276      * parameter.
    277      *
    278      * @throws ParseException which signals that an error has been reached
    279      * unexpectedly while parsing the host value.
    280      */
    281     public void setHost(String host) throws ParseException {
    282         if (sentBy == null)
    283             sentBy = new HostPort();
    284         try {
    285             Host h = new Host(host);
    286             sentBy.setHost(h);
    287         } catch (Exception e) {
    288             throw new NullPointerException(" host parameter is null");
    289         }
    290     }
    291 
    292     /**
    293     * Returns the host part of this ViaHeader.
    294     *
    295     * @return  the string value of the host
    296     */
    297     public String getHost() {
    298         if (sentBy == null)
    299             return null;
    300         else {
    301             Host host = sentBy.getHost();
    302             if (host == null)
    303                 return null;
    304             else
    305                 return host.getHostname();
    306         }
    307     }
    308 
    309     /**
    310      * Set the port part of this ViaHeader to the newly supplied <code>port</code>
    311      * parameter.
    312      *
    313      * @param port - the Integer.valueOf value of the port of this ViaHeader
    314      */
    315     public void setPort(int port) throws InvalidArgumentException {
    316 
    317         if ( port!=-1 && (port<1 || port>65535)) {
    318             throw new InvalidArgumentException( "Port value out of range -1, [1..65535]" );
    319         }
    320 
    321         if (sentBy == null)
    322             sentBy = new HostPort();
    323         sentBy.setPort(port);
    324     }
    325 
    326     /**
    327      * Set the RPort flag parameter
    328      */
    329     public void setRPort(){
    330         rPortFlag = true;
    331     }
    332 
    333     /**
    334      * Returns the port part of this ViaHeader.
    335      *
    336      * @return the integer value of the port
    337      */
    338     public int getPort() {
    339         if (sentBy == null)
    340             return -1;
    341         return sentBy.getPort();
    342     }
    343 
    344 
    345     /**
    346     * Return the rport parameter.
    347     *
    348     *@return the rport parameter or -1.
    349     */
    350        public int getRPort() {
    351          String strRport = getParameter(ParameterNames.RPORT);
    352          if (strRport != null && ! strRport.equals(""))
    353             return Integer.valueOf(strRport).intValue();
    354          else
    355             return -1;
    356          }
    357 
    358 
    359     /**
    360      * Returns the value of the transport parameter.
    361      *
    362      * @return the string value of the transport paramter of the ViaHeader
    363      */
    364     public String getTransport() {
    365         if (sentProtocol == null)
    366             return null;
    367         return sentProtocol.getTransport();
    368     }
    369 
    370     /**
    371      * Sets the value of the transport. This parameter specifies
    372      * which transport protocol to use for sending requests and responses to
    373      * this entity. The following values are defined: "udp", "tcp", "sctp",
    374      * "tls", but other values may be used also.
    375      *
    376      * @param transport - new value for the transport parameter
    377      * @throws ParseException which signals that an error has been reached
    378      * unexpectedly while parsing the transport value.
    379      */
    380     public void setTransport(String transport) throws ParseException {
    381         if (transport == null)
    382             throw new NullPointerException(
    383                 "JAIN-SIP Exception, "
    384                     + "Via, setTransport(), the transport parameter is null.");
    385         if (sentProtocol == null)
    386             sentProtocol = new Protocol();
    387         sentProtocol.setTransport(transport);
    388     }
    389 
    390     /**
    391      * Returns the value of the protocol used.
    392      *
    393      * @return the string value of the protocol paramter of the ViaHeader
    394      */
    395     public String getProtocol() {
    396         if (sentProtocol == null)
    397             return null;
    398         return sentProtocol.getProtocol();// JvB: Return name ~and~ version
    399     }
    400 
    401     /**
    402      * Sets the value of the protocol parameter. This parameter specifies
    403      * which protocol is used, for example "SIP/2.0".
    404      *
    405      * @param protocol - new value for the protocol parameter
    406      * @throws ParseException which signals that an error has been reached
    407      * unexpectedly while parsing the protocol value.
    408      */
    409     public void setProtocol(String protocol) throws ParseException {
    410         if (protocol == null)
    411             throw new NullPointerException(
    412                 "JAIN-SIP Exception, "
    413                     + "Via, setProtocol(), the protocol parameter is null.");
    414 
    415         if (sentProtocol == null)
    416             sentProtocol = new Protocol();
    417 
    418         sentProtocol.setProtocol(protocol);
    419     }
    420 
    421     /**
    422      * Returns the value of the ttl parameter, or -1 if this is not set.
    423      *
    424      * @return the integer value of the <code>ttl</code> parameter
    425      */
    426     public int getTTL() {
    427         int ttl = getParameterAsInt(ParameterNames.TTL);
    428         return ttl;
    429     }
    430 
    431     /**
    432      * Sets the value of the ttl parameter. The ttl parameter specifies the
    433      * time-to-live value when packets are sent using UDP multicast.
    434      *
    435      * @param ttl - new value of the ttl parameter
    436      * @throws InvalidArgumentException if supplied value is less than zero or
    437      * greater than 255, excluding -1 the default not set value.
    438      */
    439     public void setTTL(int ttl) throws InvalidArgumentException {
    440         if (ttl < 0 && ttl != -1)
    441             throw new InvalidArgumentException(
    442                 "JAIN-SIP Exception"
    443                     + ", Via, setTTL(), the ttl parameter is < 0");
    444         setParameter(new NameValue(ParameterNames.TTL, Integer.valueOf(ttl)));
    445     }
    446 
    447     /**
    448      * Returns the value of the <code>maddr</code> parameter, or null if this
    449      * is not set.
    450      *
    451      * @return the string value of the maddr parameter
    452      */
    453     public String getMAddr() {
    454         return getParameter(ParameterNames.MADDR);
    455     }
    456 
    457     /**
    458      * Sets the value of the <code>maddr</code> parameter of this ViaHeader. The
    459      * maddr parameter indicates the server address to be contacted for this
    460      * user, overriding any address derived from the host field.
    461      *
    462      * @param  mAddr new value of the <code>maddr</code> parameter
    463      * @throws ParseException which signals that an error has been reached
    464      * unexpectedly while parsing the mAddr value.
    465      */
    466     public void setMAddr(String mAddr) throws ParseException {
    467         if (mAddr == null)
    468             throw new NullPointerException(
    469                 "JAIN-SIP Exception, "
    470                     + "Via, setMAddr(), the mAddr parameter is null.");
    471 
    472         Host host = new Host();
    473         host.setAddress(mAddr);
    474         NameValue nameValue = new NameValue(ParameterNames.MADDR, host);
    475         setParameter(nameValue);
    476 
    477     }
    478 
    479     /**
    480      * Gets the received paramater of the ViaHeader. Returns null if received
    481      * does not exist.
    482      *
    483      * @return the string received value of ViaHeader
    484      */
    485     public String getReceived() {
    486         return getParameter(ParameterNames.RECEIVED);
    487     }
    488 
    489     /**
    490      * Sets the received parameter of ViaHeader.
    491      *
    492      * @param received - the newly supplied received parameter.
    493      * @throws ParseException which signals that an error has been reached
    494      * unexpectedly while parsing the received value.
    495      */
    496     public void setReceived(String received) throws ParseException {
    497         if (received == null)
    498             throw new NullPointerException(
    499                 "JAIN-SIP Exception, "
    500                     + "Via, setReceived(), the received parameter is null.");
    501 
    502         setParameter(ParameterNames.RECEIVED, received);
    503 
    504     }
    505 
    506     /**
    507      * Gets the branch paramater of the ViaHeader. Returns null if branch
    508      * does not exist.
    509      *
    510      * @return the string branch value of ViaHeader
    511      */
    512     public String getBranch() {
    513         return getParameter(ParameterNames.BRANCH);
    514     }
    515 
    516     /**
    517      * Sets the branch parameter of the ViaHeader to the newly supplied
    518      * branch value.
    519      *
    520      * @param branch - the new string branch parmameter of the ViaHeader.
    521      * @throws ParseException which signals that an error has been reached
    522      * unexpectedly while parsing the branch value.
    523      */
    524     public void setBranch(String branch) throws ParseException {
    525         if (branch == null || branch.length()==0)
    526             throw new NullPointerException(
    527                 "JAIN-SIP Exception, "
    528                     + "Via, setBranch(), the branch parameter is null or length 0.");
    529 
    530         setParameter(ParameterNames.BRANCH, branch);
    531     }
    532 
    533     public Object clone() {
    534         Via retval = (Via) super.clone();
    535         if (this.sentProtocol != null)
    536             retval.sentProtocol = (Protocol) this.sentProtocol.clone();
    537         if (this.sentBy != null)
    538             retval.sentBy = (HostPort) this.sentBy.clone();
    539         if ( this.getRPort() != -1)
    540             retval.setParameter(RPORT,this.getRPort());
    541         return retval;
    542     }
    543 
    544     /*
    545      * (non-Javadoc)
    546      * @see gov.nist.javax.sip.header.ViaHeaderExt#getSentByField()
    547      */
    548     public String getSentByField() {
    549         if(sentBy != null)
    550             return sentBy.encode();
    551         return null;
    552     }
    553     /*
    554      * (non-Javadoc)
    555      * @see gov.nist.javax.sip.header.ViaHeaderExt#getSentProtocolField()
    556      */
    557     public String getSentProtocolField() {
    558         if(sentProtocol != null)
    559             return sentProtocol.encode();
    560         return null;
    561     }
    562 
    563 }
    564