/*
* 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));
}
}