/*
* Copyright (C) 2005 Luca Veltri - University of Parma - Italy
*
* This file is part of MjSip (http://www.mjsip.org)
*
* MjSip is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MjSip is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MjSip; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author(s):
* Luca Veltri (luca.veltri@unipr.it)
*/
package org.zoolu.sip.message;
import org.zoolu.sip.provider.*;
import org.zoolu.sip.header.*;
import org.zoolu.sip.address.*;
import org.zoolu.sip.message.SipMethods;
import org.zoolu.net.UdpPacket;
import java.util.*;
/** Class BaseMessage implements a generic SIP Message. */
public abstract class BaseMessage
{
/** UDP */
public static final String PROTO_UDP = "udp";
/** TCP */
public static final String PROTO_TCP = "tcp";
/** TLS */
public static final String PROTO_TLS = "tls";
/** SCTP */
public static final String PROTO_SCTP = "sctp";
/** Maximum receiving packet size */
protected static int MAX_PKT_SIZE = 8000;
/** The remote ip address */
protected String remote_addr;
/** The remote port */
protected int remote_port;
/** Transport protocol */
protected String transport_proto;
/** Connection identifier */
protected ConnectionIdentifier connection_id;
/** Packet length */
// protected int packet_length;
/** The message string */
private String message;
/** Inits empty Message */
private void init()
{ // message="";
remote_addr = null;
remote_port = 0;
transport_proto = null;
connection_id = null;
}
/** Costructs a new empty Message */
public BaseMessage()
{
init();
message = "";
}
/** Costructs a new Message */
public BaseMessage(byte[] data, int offset, int len)
{
init();
message = new String(data, offset, len);
}
/** Costructs a new Message */
public BaseMessage(UdpPacket packet)
{
init();
message = new String(packet.getData(), packet.getOffset(), packet.getLength());
}
/** Costructs a new Message */
public BaseMessage(String str)
{
init();
message = new String(str);
}
/** Costructs a new Message */
public BaseMessage(BaseMessage msg)
{ // message=new String(msg.message);
message = msg.message;
remote_addr = msg.remote_addr;
remote_port = msg.remote_port;
transport_proto = msg.transport_proto;
connection_id = msg.connection_id;
// packet_length=msg.packet_length;
}
/** Creates and returns a clone of the Message */
abstract public Object clone();
// { return new Message(message);
// }
/** Sets the entire message */
public void setMessage(String message)
{
this.message = message;
}
/** Gets string representation of Message */
public String toString()
{
return message;
}
/** Gets remote ip address */
public String getRemoteAddress()
{
return remote_addr;
}
/** Gets remote port */
public int getRemotePort()
{
return remote_port;
}
/** Gets transport protocol */
public String getTransportProtocol()
{
return transport_proto;
}
/** Gets connection identifier */
public ConnectionIdentifier getConnectionId()
{
return connection_id;
}
/** Gets message length */
public int getLength()
{
return message.length();
}
/** Sets remote ip address */
public void setRemoteAddress(String addr)
{
remote_addr = addr;
}
/** Sets remote port */
public void setRemotePort(int port)
{
remote_port = port;
}
/** Sets transport protocol */
public void setTransport(String proto)
{
transport_proto = proto;
}
/** Sets connection identifier */
public void setConnectionId(ConnectionIdentifier conn_id)
{
connection_id = conn_id;
}
/** Gets the inique DialogIdentifier for an INCOMING message */
public DialogIdentifier getDialogId()
{
String call_id = getCallIdHeader().getCallId();
String local_tag, remote_tag;
if(isRequest())
{
local_tag = getToHeader().getTag();
remote_tag = getFromHeader().getTag();
}
else
{
local_tag = getFromHeader().getTag();
remote_tag = getToHeader().getTag();
}
return new DialogIdentifier(call_id, local_tag, remote_tag);
}
/** Gets the inique TransactionIdentifier */
public TransactionIdentifier getTransactionId()
{
String call_id = getCallIdHeader().getCallId();
ViaHeader top_via = getViaHeader();
String branch = null;
if(top_via.hasBranch())
branch = top_via.getBranch();
String sent_by = top_via.getSentBy();
CSeqHeader cseqh = getCSeqHeader();
long seqn = cseqh.getSequenceNumber();
String method = cseqh.getMethod();
return new TransactionIdentifier(call_id, seqn, method, sent_by, branch);
}
/** Gets the MethodIdentifier */
public MethodIdentifier getMethodId()
{
String method = getCSeqHeader().getMethod();
return new MethodIdentifier(method);
}
// **************************** Requests ****************************/
/** Whether Message is a Request */
public boolean isRequest() throws NullPointerException
{ // Req-Line = Method ' ' SIP-URL ' ' "SIP/2.0" CRLF
if(message == null || isResponse())
return false;
String firstline = (new SipParser(message)).getLine();
String version = (new SipParser(firstline)).skipString().skipString().getString();
if(version == null || version.length() < 4)
return false;
version = version.substring(0, 4);
String target = "SIP/";
// if (version.compareToIgnoreCase(target)==0) return true;
if(version.equalsIgnoreCase(target))
return true;
return false;
}
/** Whether Message is a <i>method</i> request */
public boolean isRequest(String method)
{ // if (message==null) return false;
if(message.startsWith(method))
return true;
else
return false;
}
/** Whether Message is a Method that creates a dialog */
public boolean createsDialog()
{
if(!isRequest())
return false;
// else
String method = getRequestLine().getMethod();
for (int i = 0; i < SipMethods.dialog_methods.length; i++)
if(method.equalsIgnoreCase(SipMethods.dialog_methods[i]))
return true;
// else
return false;
}
/** Whether Message is an Invite */
public boolean isInvite()
{
return isRequest(SipMethods.INVITE);
}
/** Whether Message is a Register */
public boolean isRegister()
{
return isRequest(SipMethods.REGISTER);
}
/** Whether Message is a Cancel */
public boolean isCancel()
{
return isRequest(SipMethods.CANCEL);
}
/** Whether Message is a Bye */
public boolean isBye()
{
return isRequest(SipMethods.BYE);
}
/** Whether Message is an Ack */
public boolean isAck()
{
return isRequest(SipMethods.ACK);
}
/** Whether Message is an Info */
public boolean isInfo()
{
return isRequest(SipMethods.INFO);
}
/** Whether Message is an Option */
public boolean isOption()
{
return isRequest(SipMethods.OPTION);
}
/** Whether Message has Request-line */
protected boolean hasRequestLine()
{
return isRequest();
}
/**
* Gets RequestLine in Message (Returns null if called for no request
* message)
*/
public RequestLine getRequestLine()
{
if(!isRequest())
{ // printWarning("getRequestLine(): called for no request message\n",1);
return null;
}
SipParser par = new SipParser(message);
String method = par.getString();
par.skipWSP();
par = new SipParser(par.subParser(par.indexOfEOH() - par.getPos()));
return new RequestLine(method, par.getSipURL());
}
/** Sets RequestLine of the Message */
public void setRequestLine(RequestLine rl)
{
if(hasRequestLine())
removeRequestLine();
String value = rl.toString();
message = value + message;
}
/** Removes RequestLine of the Message */
public void removeRequestLine()
{
if(!isRequest())
return;
removeFirstLine();
}
// **************************** Responses ****************************/
/** Whether Message is a Response */
public boolean isResponse() throws NullPointerException
{ // Status-Line = "SIP/2.0" ' ' Status-Code ' 'Reason-Phrase" CRLF
// if (message==null) return false;
if(message == null || message.length() < 4)
return false;
String version = message.substring(0, 4);
String target = "SIP/";
// if (version.compareToIgnoreCase(target)==0) return true;
if(version.equalsIgnoreCase(target))
return true;
return false;
}
/** Whether Message has Status-line */
protected boolean hasStatusLine()
{
return isResponse();
}
/**
* Gets StautsLine in Message (Returns null if called for no response
* message)
*/
public StatusLine getStatusLine()
{
if(!isResponse())
{ // printWarning("getStatusLine(): called for no response message\n",1);
return null;
}
SipParser par = new SipParser(message);
par.skipString().skipWSP(); // "SIP/2.0 "
int code = par.getInt();
int begin = par.getPos();
int end = par.indexOfEOH();
String reason = message.substring(begin, end).trim();
return new StatusLine(code, reason);
}
/** Sets StatusLine of the Message */
public void setStatusLine(StatusLine sl)
{
if(hasStatusLine())
removeStatusLine();
message = sl.toString() + message;
}
/** Removes StatusLine of the Message */
public void removeStatusLine()
{
if(!isResponse())
return;
removeFirstLine();
}
// **************************** Generic Headers ****************************/
/** Returns the transaction method */
public String getTransactionMethod()
{
return getCSeqHeader().getMethod();
}
/** Gets the first line of the Message */
public String getFirstLine()
{
if(isRequest())
return getRequestLine().toString();
if(isResponse())
return getStatusLine().toString();
return null;
}
/** Sets Request/Status Line of the Message */
/*
* private void setFirstLine(String value) { message=value+" \r\n"+message; }
*/
/** Removes Request\Status Line of the Message */
protected void removeFirstLine()
{
message = message.substring((new SipParser(message)).indexOfNextHeader());
}
/** Whether Message has any headers of specified name */
public boolean hasHeader(String name)
{
Header hd = getHeader(name);
if(hd == null)
return false;
else
return true;
}
/**
* Gets the first Header of specified name (Returns null if no Header is
* found)
*/
public Header getHeader(String hname)
{
SipParser par = new SipParser(message);
return par.getHeader(hname);
}
/**
* Gets a Vector of all Headers of specified name (Returns empty Vector if no
* Header is found)
*/
public Vector getHeaders(String hname)
{
Vector v = new Vector();
SipParser par = new SipParser(message);
Header h;
while ((h = par.getHeader(hname)) != null)
{
v.addElement(h);
}
return v;
}
/**
* Adds Header at the top/bottom. The bottom is considered before the
* Content-Length and Content-Type headers
*/
public void addHeader(Header header, boolean top)
{
addHeaders(header.toString(), top);
}
/** Adds a Vector of Headers at the top/bottom */
public void addHeaders(Vector headers, boolean top)
{
String str = "";
for (int i = 0; i < headers.size(); i++)
str += ((Header) headers.elementAt(i)).toString();
addHeaders(str, top);
}
/** Adds MultipleHeader(s) <i>mheader</i> at the top/bottom */
public void addHeaders(MultipleHeader mheader, boolean top)
{
addHeaders(mheader.toString(), top);
}
/**
* Adds a one or more Headers at the top/bottom. The bottom is considered
* before the Content-Length and Content-Type headers
*/
protected void addHeaders(String str, boolean top)
{
int i, aux;
if(top)
{
if(this.hasRequestLine() || this.hasStatusLine())
{
SipParser par = new SipParser(message);
par.goToNextHeader();
i = par.getPos();
}
else
i = 0;
}
else
{
SipParser par = new SipParser(message);
// index the end of headers
i = par.goToEndOfLastHeader().goToNextLine().getPos();
par = new SipParser(message);
// if Content_Length is present, jump before
aux = par.indexOfHeader(SipHeaders.Content_Length);
if(aux < i)
i = aux;
// if Content_Type is present, jump before
aux = par.indexOfHeader(SipHeaders.Content_Type);
if(aux < i)
i = aux;
}
String head = message.substring(0, i);
String tail = message.substring(i);
String new_message = head.concat(str);
new_message = new_message.concat(tail);
message = new_message;
}
/** Adds Headers on position <i>index</i> within the Message */
protected void addHeaders(String str, int index)
{
if(index > message.length())
index = message.length();
message = message.substring(0, index) + str + message.substring(index);
}
/**
* Adds Header before the first header <i>refer_header</i> .
* <p>
* If there is no header of such type, it is added at top
*/
public void addHeaderBefore(Header new_header, String refer_header)
{
addHeadersBefore(new_header.toString(), refer_header);
}
/**
* Adds MultipleHeader(s) before the first header <i>refer_header</i> .
* <p>
* If there is no header of such type, they are added at top
*/
public void addHeadersBefore(MultipleHeader mheader, String refer_header)
{
addHeadersBefore(mheader.toString(), refer_header);
}
/**
* Adds Headers before the first header <i>refer_header</i> .
* <p>
* If there is no header of such type, they are added at top
*/
protected void addHeadersBefore(String str, String refer_header)
{
if(!hasHeader(refer_header))
addHeaders(str, true);
else
{
SipParser par = new SipParser(message);
par.goTo(refer_header);
int here = par.getPos();
message = message.substring(0, here) + str + message.substring(here);
}
}
/**
* Adds Header after the first header <i>refer_header</i> .
* <p>
* If there is no header of such type, it is added at bottom
*/
public void addHeaderAfter(Header new_header, String refer_header)
{
addHeadersAfter(new_header.toString(), refer_header);
}
/**
* Adds MultipleHeader(s) after the first header <i>refer_header</i> .
* <p>
* If there is no header of such type, they are added at bottom
*/
public void addHeadersAfter(MultipleHeader mheader, String refer_header)
{
addHeadersAfter(mheader.toString(), refer_header);
}
/**
* Adds Headers after the first header <i>refer_header</i> .
* <p>
* If there is no header of such type, they are added at bottom
*/
protected void addHeadersAfter(String str, String refer_header)
{
if(!hasHeader(refer_header))
addHeaders(str, false);
else
{
SipParser par = new SipParser(message);
par.goTo(refer_header);
int here = par.indexOfNextHeader();
message = message.substring(0, here) + str + message.substring(here);
}
}
/** Removes first Header of specified name */
public void removeHeader(String hname)
{
removeHeader(hname, true);
}
/** Removes first (or last) Header of specified name */
public void removeHeader(String hname, boolean first)
{
String[] target = {'\n' + hname, '\r' + hname};
SipParser par = new SipParser(message);
par.goTo(target);
if(!par.hasMore())
return;
if(!first)
while (true)
{
int next = par.indexOf(target);
if(next < 0)
break;
par.setPos(next);
}
par.skipChar();
String head = message.substring(0, par.getPos());
par.goToNextHeader();
String tail = message.substring(par.getPos());
message = head.concat(tail);
}
/** Sets the new Header (removing any previous headers of the same name) */
/*
* public void setHeader(Header hd) { if (hasHeader(hd.getName()))
* removeAllHeaders(hd.getName()); addHeader(hd,false); }
*/
/** Sets the Header <i>hd</i> removing any previous headers of the same type */
public void setHeader(Header hd)
{
String hname = hd.getName();
if(hasHeader(hname))
{
int index = (new SipParser(message)).indexOfHeader(hname);
removeAllHeaders(hname);
addHeaders(hd.toString(), index);
}
else
addHeader(hd, false);
}
/** Removes all Headers of specified name */
public void removeAllHeaders(String hname)
{
String[] target = {'\n' + hname, '\r' + hname};
SipParser par = new SipParser(message);
par.goTo(target);
while (par.hasMore())
{
par.skipChar();
String head = message.substring(0, par.getPos());
String tail = message.substring(par.indexOfNextHeader());
message = head.concat(tail);
par = new SipParser(message, par.getPos() - 1);
par.goTo(target);
}
}
/** Sets MultipleHeader <i>mheader</i> */
/*
* public void setHeaders(MultipleHeader mheader) { if
* (hasHeader(mheader.getName())) removeAllHeaders(mheader.getName());
* addHeaders(mheader,false); }
*/
/** Sets MultipleHeader <i>mheader</i> */
public void setHeaders(MultipleHeader mheader)
{
String hname = mheader.getName();
if(hasHeader(hname))
{
int index = (new SipParser(message)).indexOfHeader(hname);
removeAllHeaders(hname);
addHeaders(mheader.toString(), index);
}
else
addHeaders(mheader, false);
}
// **************************** Specific Headers
// ****************************/
/** Whether Message has MaxForwardsHeader */
public boolean hasMaxForwardsHeader()
{
return hasHeader(SipHeaders.Max_Forwards);
}
/** Gets MaxForwardsHeader of Message */
public MaxForwardsHeader getMaxForwardsHeader()
{
Header h = getHeader(SipHeaders.Max_Forwards);
if(h == null)
return null;
else
return new MaxForwardsHeader(h);
}
/** Sets MaxForwardsHeader of Message */
public void setMaxForwardsHeader(MaxForwardsHeader mfh)
{
setHeader(mfh);
}
/** Removes MaxForwardsHeader from Message */
public void removeMaxForwardsHeader()
{
removeHeader(SipHeaders.Max_Forwards);
}
/** Whether Message has FromHeader */
public boolean hasFromHeader()
{
return hasHeader(SipHeaders.From);
}
/** Gets FromHeader of Message */
public FromHeader getFromHeader()
{
Header h = getHeader(SipHeaders.From);
if(h == null)
return null;
else
return new FromHeader(h);
}
/** Sets FromHeader of Message */
public void setFromHeader(FromHeader fh)
{
setHeader(fh);
}
/** Removes FromHeader from Message */
public void removeFromHeader()
{
removeHeader(SipHeaders.From);
}
/** Whether Message has ToHeader */
public boolean hasToHeader()
{
return hasHeader(SipHeaders.To);
}
/** Gets ToHeader of Message */
public ToHeader getToHeader()
{
Header h = getHeader(SipHeaders.To);
if(h == null)
return null;
else
return new ToHeader(h);
}
/** Sets ToHeader of Message */
public void setToHeader(ToHeader th)
{
setHeader(th);
}
/** Removes ToHeader from Message */
public void removeToHeader()
{
removeHeader(SipHeaders.To);
}
/** Whether Message has ContactHeader */
public boolean hasContactHeader()
{
return hasHeader(SipHeaders.Contact);
}
/**
* <b>Deprecated</b>. Gets ContactHeader of Message. Use getContacts
* instead.
*/
public ContactHeader getContactHeader()
{ // Header h=getHeader(SipHeaders.Contact);
// if (h==null) return null; else return new ContactHeader(h);
MultipleHeader mh = getContacts();
if(mh == null)
return null;
return new ContactHeader(mh.getTop());
}
/** Adds ContactHeader */
public void addContactHeader(ContactHeader ch, boolean top)
{
addHeader(ch, top);
}
/** Sets ContactHeader */
public void setContactHeader(ContactHeader ch)
{
if(hasContactHeader())
removeContacts();
addHeader(ch, false);
}
/** Gets a MultipleHeader of Contacts */
public MultipleHeader getContacts()
{
Vector v = getHeaders(SipHeaders.Contact);
if(v.size() > 0)
return new MultipleHeader(v);
else
return null;
}
/** Adds Contacts */
public void addContacts(MultipleHeader contacts, boolean top)
{
addHeaders(contacts, top);
}
/** Sets Contacts */
public void setContacts(MultipleHeader contacts)
{
if(hasContactHeader())
removeContacts();
addContacts(contacts, false);
}
/** Removes ContactHeaders from Message */
public void removeContacts()
{
removeAllHeaders(SipHeaders.Contact);
}
/** Whether Message has ViaHeaders */
public boolean hasViaHeader()
{
return hasHeader(SipHeaders.Via);
}
/** Adds ViaHeader at the top */
public void addViaHeader(ViaHeader vh)
{
addHeader(vh, true);
}
/** Gets the first ViaHeader */
public ViaHeader getViaHeader()
{ // Header h=getHeader(SipHeaders.Via);
// if (h==null) return null; else return new ViaHeader(h);
MultipleHeader mh = getVias();
if(mh == null)
return null;
return new ViaHeader(mh.getTop());
}
/** Removes the top ViaHeader */
public void removeViaHeader()
{ // removeHeader(SipHeaders.Via);
MultipleHeader mh = getVias();
mh.removeTop();
setVias(mh);
}
/** Gets all Vias */
public MultipleHeader getVias()
{
Vector v = getHeaders(SipHeaders.Via);
if(v.size() > 0)
return new MultipleHeader(v);
else
return null;
}
/** Adds Vias */
public void addVias(MultipleHeader vias, boolean top)
{
addHeaders(vias, top);
}
/** Sets Vias */
public void setVias(MultipleHeader vias)
{
if(hasViaHeader())
removeVias();
addContacts(vias, true);
}
/** Removes ViaHeaders from Message (if any exists) */
public void removeVias()
{
removeAllHeaders(SipHeaders.Via);
}
/** Whether Message has RouteHeader */
public boolean hasRouteHeader()
{
return hasHeader(SipHeaders.Route);
}
/** Adds RouteHeader at the top */
public void addRouteHeader(RouteHeader h)
{
addHeaderAfter(h, SipHeaders.Via);
}
/** Adds multiple Route headers at the top */
public void addRoutes(MultipleHeader routes)
{
addHeadersAfter(routes, SipHeaders.Via);
}
/** Gets the top RouteHeader */
public RouteHeader getRouteHeader()
{ // Header h=getHeader(SipHeaders.Route);
// if (h==null) return null; else return new RouteHeader(h);
MultipleHeader mh = getRoutes();
if(mh == null)
return null;
return new RouteHeader(mh.getTop());
}
/** Gets the whole route */
public MultipleHeader getRoutes()
{
Vector v = getHeaders(SipHeaders.Route);
if(v.size() > 0)
return new MultipleHeader(v);
else
return null;
}
/** Removes the top RouteHeader */
public void removeRouteHeader()
{ // removeHeader(SipHeaders.Route);
MultipleHeader mh = getRoutes();
mh.removeTop();
setRoutes(mh);
}
/** Removes all RouteHeaders from Message (if any exists) */
public void removeRoutes()
{
removeAllHeaders(SipHeaders.Route);
}
/** Sets the whole route */
public void setRoutes(MultipleHeader routes)
{
if(hasRouteHeader())
removeRoutes();
addRoutes(routes);
}
/** Whether Message has RecordRouteHeader */
public boolean hasRecordRouteHeader()
{
return hasHeader(SipHeaders.Record_Route);
}
/** Adds RecordRouteHeader at the top */
public void addRecordRouteHeader(RecordRouteHeader rr)
{ // addHeaderAfter(rr,SipHeaders.Via);
addHeaderAfter(rr, SipHeaders.CSeq);
}
/** Adds multiple RecordRoute headers at the top */
public void addRecordRoutes(MultipleHeader routes)
{ // addHeadersAfter(routes,SipHeaders.Via);
addHeadersAfter(routes, SipHeaders.CSeq);
}
/** Gets the top RecordRouteHeader */
public RecordRouteHeader getRecordRouteHeader()
{ // Header h=getHeader(SipHeaders.Record_Route);
// if (h==null) return null; else return new RecordRouteHeader(h);
MultipleHeader mh = getRecordRoutes();
if(mh == null)
return null;
return new RecordRouteHeader(mh.getTop());
}
/** Gets the whole RecordRoute headers */
public MultipleHeader getRecordRoutes()
{
Vector v = getHeaders(SipHeaders.Record_Route);
if(v.size() > 0)
return new MultipleHeader(v);
else
return null;
}
/** Removes the top RecordRouteHeader */
public void removeRecordRouteHeader()
{ // removeHeader(SipHeaders.Record_Route);
MultipleHeader mh = getRecordRoutes();
mh.removeTop();
setRecordRoutes(mh);
}
/** Removes all RecordRouteHeader from Message (if any exists) */
public void removeRecordRoutes()
{
removeAllHeaders(SipHeaders.Record_Route);
}
/** Sets the whole RecordRoute headers */
public void setRecordRoutes(MultipleHeader routes)
{
if(hasRecordRouteHeader())
removeRecordRoutes();
addRecordRoutes(routes);
}
/** Whether Message has CSeqHeader */
public boolean hasCSeqHeader()
{
return hasHeader(SipHeaders.CSeq);
}
/** Gets CSeqHeader of Message */
public CSeqHeader getCSeqHeader()
{
Header h = getHeader(SipHeaders.CSeq);
if(h == null)
return null;
else
return new CSeqHeader(h);
}
/** Sets CSeqHeader of Message */
public void setCSeqHeader(CSeqHeader csh)
{
setHeader(csh);
}
/** Removes CSeqHeader from Message */
public void removeCSeqHeader()
{
removeHeader(SipHeaders.CSeq);
}
/** Whether has CallIdHeader */
public boolean hasCallIdHeader()
{
return hasHeader(SipHeaders.Call_ID);
}
/** Sets CallIdHeader of Message */
public void setCallIdHeader(CallIdHeader cih)
{
setHeader(cih);
}
/** Gets CallIdHeader of Message */
public CallIdHeader getCallIdHeader()
{
Header h = getHeader(SipHeaders.Call_ID);
if(h == null)
return null;
else
return new CallIdHeader(h);
}
/** Removes CallIdHeader from Message */
public void removeCallIdHeader()
{
removeHeader(SipHeaders.Call_ID);
}
/** Whether Message has SubjectHeader */
public boolean hasSubjectHeader()
{
return hasHeader(SipHeaders.Subject);
}
/** Sets SubjectHeader of Message */
public void setSubjectHeader(SubjectHeader sh)
{
setHeader(sh);
}
/** Gets SubjectHeader of Message */
public SubjectHeader getSubjectHeader()
{
Header h = getHeader(SipHeaders.Subject);
if(h == null)
return null;
else
return new SubjectHeader(h);
}
/** Removes SubjectHeader from Message */
public void removeSubjectHeader()
{
removeHeader(SipHeaders.Subject);
}
/** Whether Message has DateHeader */
public boolean hasDateHeader()
{
return hasHeader(SipHeaders.Date);
}
/** Gets DateHeader of Message */
public DateHeader getDateHeader()
{
Header h = getHeader(SipHeaders.Date);
if(h == null)
return null;
else
return new DateHeader(h);
}
/** Sets DateHeader of Message */
public void setDateHeader(DateHeader dh)
{
setHeader(dh);
}
/** Removes DateHeader from Message (if it exists) */
public void removeDateHeader()
{
removeHeader(SipHeaders.Date);
}
/** Whether has UserAgentHeader */
public boolean hasUserAgentHeader()
{
return hasHeader(SipHeaders.User_Agent);
}
/** Sets UserAgentHeader */
public void setUserAgentHeader(UserAgentHeader h)
{
setHeader(h);
}
/** Gets UserAgentHeader */
public UserAgentHeader getUserAgentHeader()
{
Header h = getHeader(SipHeaders.User_Agent);
if(h == null)
return null;
else
return new UserAgentHeader(h);
}
/** Removes UserAgentHeader */
public void removeUserAgentHeader()
{
removeHeader(SipHeaders.User_Agent);
}
/** Whether has ServerHeader */
public boolean hasServerHeader()
{
return hasHeader(SipHeaders.Server);
}
/** Sets ServerHeader */
public void setServerHeader(ServerHeader h)
{
setHeader(h);
}
/** Gets ServerHeader */
public ServerHeader getServerHeader()
{
Header h = getHeader(SipHeaders.Server);
if(h == null)
return null;
else
return new ServerHeader(h);
}
/** Removes ServerHeader */
public void removeServerHeader()
{
removeHeader(SipHeaders.Server);
}
/** Whether has AcceptHeader */
public boolean hasAcceptHeader()
{
return hasHeader(SipHeaders.Accept);
}
/** Sets AcceptHeader */
public void setAcceptHeader(AcceptHeader h)
{
setHeader(h);
}
/** Gets AcceptHeader */
public AcceptHeader getAcceptHeader()
{
Header h = getHeader(SipHeaders.Accept);
if(h == null)
return null;
else
return new AcceptHeader(h);
}
/** Removes AcceptHeader */
public void removeAcceptHeader()
{
removeHeader(SipHeaders.Accept);
}
/** Whether has AlertInfoHeader */
public boolean hasAlertInfoHeader()
{
return hasHeader(SipHeaders.Alert_Info);
}
/** Sets AlertInfoHeader */
public void setAlertInfoHeader(AlertInfoHeader h)
{
setHeader(h);
}
/** Gets AlertInfoHeader */
public AlertInfoHeader getAlertInfoHeader()
{
Header h = getHeader(SipHeaders.Alert_Info);
if(h == null)
return null;
else
return new AlertInfoHeader(h);
}
/** Removes AlertInfoHeader */
public void removeAlertInfoHeader()
{
removeHeader(SipHeaders.Alert_Info);
}
/** Whether has AllowHeader */
public boolean hasAllowHeader()
{
return hasHeader(SipHeaders.Allow);
}
/** Sets AllowHeader */
public void setAllowHeader(AllowHeader h)
{
setHeader(h);
}
/** Gets AllowHeader */
public AllowHeader getAllowHeader()
{
Header h = getHeader(SipHeaders.Allow);
if(h == null)
return null;
else
return new AllowHeader(h);
}
/** Removes AllowHeader */
public void removeAllowHeader()
{
removeHeader(SipHeaders.Allow);
}
/** Whether Message has ExpiresHeader */
public boolean hasExpiresHeader()
{
return hasHeader(SipHeaders.Expires);
}
/** Gets ExpiresHeader of Message */
public ExpiresHeader getExpiresHeader()
{
Header h = getHeader(SipHeaders.Expires);
if(h == null)
return null;
else
return new ExpiresHeader(h);
}
/** Sets ExpiresHeader of Message */
public void setExpiresHeader(ExpiresHeader eh)
{
setHeader(eh);
}
/** Removes ExpiresHeader from Message (if it exists) */
public void removeExpiresHeader()
{
removeHeader(SipHeaders.Expires);
}
/** Whether Message has ContentTypeHeader */
public boolean hasContentTypeHeader()
{
return hasHeader(SipHeaders.Content_Type);
}
/** Gets ContentTypeHeader of Message */
public ContentTypeHeader getContentTypeHeader()
{
Header h = getHeader(SipHeaders.Content_Type);
if(h == null)
return null;
else
return new ContentTypeHeader(h);
}
/** Sets ContentTypeHeader of Message */
protected void setContentTypeHeader(ContentTypeHeader cth)
{
setHeader(cth);
}
/** Removes ContentTypeHeader from Message (if it exists) */
protected void removeContentTypeHeader()
{
removeHeader(SipHeaders.Content_Type);
}
/** Whether Message has ContentLengthHeader */
public boolean hasContentLengthHeader()
{
return hasHeader(SipHeaders.Content_Length);
}
/** Gets ContentLengthHeader of Message */
public ContentLengthHeader getContentLengthHeader()
{
Header h = getHeader(SipHeaders.Content_Length);
if(h == null)
return null;
else
return new ContentLengthHeader(h);
}
/** Sets ContentLengthHeader of Message */
protected void setContentLengthHeader(ContentLengthHeader clh)
{
setHeader(clh);
}
/** Removes ContentLengthHeader from Message (if it exists) */
protected void removeContentLengthHeader()
{
removeHeader(SipHeaders.Content_Length);
}
/** Whether Message has Body */
public boolean hasBody()
{
if(hasContentLengthHeader())
return getContentLengthHeader().getContentLength() > 0;
else
return hasContentTypeHeader();
}
/** Gets body(content) type */
public String getBodyType()
{
return getContentTypeHeader().getContentType();
}
/** Sets the message body */
public void setBody(String content_type, String body)
{
removeBody();
if(body != null && body.length() > 0)
{
setContentTypeHeader(new ContentTypeHeader(content_type));
setContentLengthHeader(new ContentLengthHeader(body.length()));
message = message + "\r\n" + body;
}
else
{
setContentLengthHeader(new ContentLengthHeader(0));
message = message + "\r\n";
}
}
/** Sets sdp body */
public void setBody(String body)
{
setBody("application/sdp", body);
}
/**
* Gets message body. The end of body is evaluated from the Content-Length
* header if present (SIP-RFC compliant), or from the end of message if no
* Content-Length header is present (non-SIP-RFC compliant)
*/
public String getBody()
{ // if (!hasBody()) return "";
if(!hasBody())
return null;
int begin = (new SipParser(message)).goToBody().getPos();
int len;
// the following 'if' is for robustness with non SIP-compliant UAs;
// copliant UAs must insert Content-Length header when body is present..
if(this.hasContentLengthHeader())
len = getContentLengthHeader().getContentLength();
else
{ // printWarning("No Content-Length header found for the Body",3);
len = message.length() - begin;
}
int end = begin + len;
if(end > message.length())
{ // printWarning("Found a Message Body shorter than Content-Length",3);
end = message.length();
}
return message.substring(begin, end);
}
/** Removes the message body (if it exists) and the final empty line */
public void removeBody()
{
int pos = (new SipParser(message)).goToEndOfLastHeader().goToNextLine().getPos();
message = message.substring(0, pos);
removeContentLengthHeader();
removeContentTypeHeader();
}
// **************************** Authentication ****************************/
/** Whether has AuthenticationInfoHeader */
public boolean hasAuthenticationInfoHeader()
{
return hasHeader(SipHeaders.Authentication_Info);
}
/** Sets AuthenticationInfoHeader */
public void setAuthenticationInfoHeader(AuthenticationInfoHeader h)
{
setHeader(h);
}
/** Gets AuthenticationInfoHeader */
public AuthenticationInfoHeader getAuthenticationInfoHeader()
{
Header h = getHeader(SipHeaders.Authentication_Info);
if(h == null)
return null;
else
return new AuthenticationInfoHeader(h);
}
/** Removes AuthenticationInfoHeader */
public void removeAuthenticationInfoHeader()
{
removeHeader(SipHeaders.Authentication_Info);
}
/** Whether has AuthorizationHeader */
public boolean hasAuthorizationHeader()
{
return hasHeader(SipHeaders.Authorization);
}
/** Sets AuthorizationHeader */
public void setAuthorizationHeader(AuthorizationHeader h)
{
setHeader(h);
}
/** Gets AuthorizationHeader */
public AuthorizationHeader getAuthorizationHeader()
{
Header h = getHeader(SipHeaders.Authorization);
if(h == null)
return null;
else
return new AuthorizationHeader(h);
}
/** Removes AuthorizationHeader */
public void removeAuthorizationHeader()
{
removeHeader(SipHeaders.Authorization);
}
/** Whether has WwwAuthenticateHeader */
public boolean hasWwwAuthenticateHeader()
{
return hasHeader(SipHeaders.WWW_Authenticate);
}
/** Sets WwwAuthenticateHeader */
public void setWwwAuthenticateHeader(WwwAuthenticateHeader h)
{
setHeader(h);
}
/** Gets WwwAuthenticateHeader */
public WwwAuthenticateHeader getWwwAuthenticateHeader()
{
Header h = getHeader(SipHeaders.WWW_Authenticate);
if(h == null)
return null;
else
return new WwwAuthenticateHeader(h);
}
/** Removes WwwAuthenticateHeader */
public void removeWwwAuthenticateHeader()
{
removeHeader(SipHeaders.WWW_Authenticate);
}
/** Whether has ProxyAuthenticateHeader */
public boolean hasProxyAuthenticateHeader()
{
return hasHeader(SipHeaders.Proxy_Authenticate);
}
/** Sets ProxyAuthenticateHeader */
public void setProxyAuthenticateHeader(ProxyAuthenticateHeader h)
{
setHeader(h);
}
/** Gets ProxyAuthenticateHeader */
public ProxyAuthenticateHeader getProxyAuthenticateHeader()
{
Header h = getHeader(SipHeaders.Proxy_Authenticate);
if(h == null)
return null;
else
return new ProxyAuthenticateHeader(h);
}
/** Removes ProxyAuthenticateHeader */
public void removeProxyAuthenticateHeader()
{
removeHeader(SipHeaders.Proxy_Authenticate);
}
/** Whether has ProxyAuthorizationHeader */
public boolean hasProxyAuthorizationHeader()
{
return hasHeader(SipHeaders.Proxy_Authorization);
}
/** Sets ProxyAuthorizationHeader */
public void setProxyAuthorizationHeader(ProxyAuthorizationHeader h)
{
setHeader(h);
}
/** Gets ProxyAuthorizationHeader */
public ProxyAuthorizationHeader getProxyAuthorizationHeader()
{
Header h = getHeader(SipHeaders.Proxy_Authorization);
if(h == null)
return null;
else
return new ProxyAuthorizationHeader(h);
}
/** Removes ProxyAuthorizationHeader */
public void removeProxyAuthorizationHeader()
{
removeHeader(SipHeaders.Proxy_Authorization);
}
// **************************** RFC 2543 Legacy ****************************/
/**
* Checks whether the next Route is formed according to RFC2543 Strict Route
* and adapts the message.
*/
public void rfc2543RouteAdapt()
{
if(hasRouteHeader())
{
MultipleHeader mrh = getRoutes();
RouteHeader rh = new RouteHeader(mrh.getTop());
if(!(new RouteHeader(mrh.getTop())).getNameAddress().getAddress().hasLr())
{ // re-format the message according to the RFC2543 Strict Route rule
SipURL next_hop = (new RouteHeader(mrh.getTop())).getNameAddress().getAddress();
SipURL recipient = getRequestLine().getAddress();
mrh.removeTop();
mrh.addBottom(new RouteHeader(new NameAddress(recipient)));
setRoutes(mrh);
setRequestLine(new RequestLine(getRequestLine().getMethod(), next_hop));
}
}
}
/**
* Changes form RFC2543 Strict Route to RFC3261 Lose Route.
* <p>
* The Request-URI is replaced with the last value from the Route header, and
* that value is removed from the Route header.
*/
public void rfc2543toRfc3261RouteUpdate()
{ // the message is formed according with RFC2543 strict route
// the next hop is the request-uri
// the recipient of the message is the last Route value
RequestLine request_line = getRequestLine();
SipURL next_hop = request_line.getAddress();
MultipleHeader mrh = getRoutes();
SipURL target = (new RouteHeader(mrh.getBottom())).getNameAddress().getAddress();
mrh.removeBottom();
next_hop.addLr();
mrh.addTop(new RouteHeader(new NameAddress(next_hop)));
removeRoutes();
addRoutes(mrh);
setRequestLine(new RequestLine(request_line.getMethod(), target));
}
}