basemessage.java

来自「结构非常清晰的SIP协议栈」· Java 代码 · 共 1,256 行 · 第 1/3 页

JAVA
1,256
字号
/*
 * 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 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?