⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sipcall.java

📁 Java SIP
💻 JAVA
字号:
/* * This file was derived from libdissipate, an open source SIP library. The original file  * was modified on 1/23/2001.  Please see * http://www.div8.net/dissipate for more information. * * Copyright (c) 2000 Billy Biggs <bbiggs@div8.net> * * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. *  * This library 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 Library General Public * License for more details. *  * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * *//** * class SipCall *  * A classfor referencing a specific SIP call. *  * This code has been generated using C2J++ * C2J++ is based on Chris Laffra's C2J (laffra@watson.ibm.com) * Read general disclaimer distributed with C2J++ before using this code * For information about C2J++, send mail to Ilya_Tilevich@ibi.com */package org.mitre.jsip;import java.util.ArrayList;import java.util.ListIterator;import java.util.Date;import java.util.Random;public class SipCall extends Object{    /**   * Creates a new call for a given SipUser   */    public SipCall( SipUser local, String id ) {	this( local, id, UnknownCall );    }    public SipCall( SipUser local, String id, int ctype )  {    callstatus = Unconnected;    if ( id == null ) {      callid = SipMessage.createCallId();    } else {      callid = id;    }    // Remember to nuke all members and transactions    members = new ArrayList();    transactions = new ArrayList();    Date tv = new Date();    Random rand = new Random(tv.getTime());    lastseq = rand.nextInt( 8000 );    parent = local.parent();    calltype = ctype;    hasroute = false;    localuri = local.getUri();    localuri.generateTag();    parent.addCall( this );  }  /**   * getCallStatus   * @return CallStatus   */  public int getCallStatus()  { return callstatus; }  /**   * @return CallType   */  public int getCallType()  { return calltype; }  /**   * setCallType   * @param newtype   */  public void setCallType(int newtype)  {    calltype = newtype;    parent.callTypeUpdated();  }  /**   * Returns the local URI that we are known by for this call.   * If there is none, returns the URI of our client parent.   * @return SipUri &   */  public SipUri localAddress()  { return localuri; }  /**   * Returns the associated call ID   * @return String &   */  public String getCallId()  { return callid; }  /**   * Tries to find a SipCallMember for the given URI.   *   * @param uri   * @return SipCallMember*   */  public SipCallMember getMember(SipUri uri)  {    SipCallMember  scm;    for (ListIterator li = members.listIterator(); li.hasNext(); ) {      scm = (SipCallMember)li.next();      if ( uri.equals( scm.getUri() ) ) {	return scm;      }    }    return null;  }  /**   * Returns the subject for this call.   *   * @return String   */  public String getSubject()  { return subject; }  /**   * Set the subject for this call. Will be used on all outgoing INVITEs sent afterwards.   *   * @param newsubject   */  public void setSubject(String newsubject)  {    subject = newsubject;    subjectChanged();  }    /**     * getTransactionList     * @return Tranlist     */    public ArrayList getTransactionList() {	return transactions;    }  /**   * Sends a SIP request under this call to the given call member.    * Returns a SipTransaction for tracking   */    public SipTransaction newRequest( SipCallMember member, int meth, 				      String body, MimeContentType bodytype )    {	return newRequest( member, meth, body, bodytype, null );    }    public SipTransaction newRequest( SipCallMember member, int meth, 				      String body, MimeContentType bodytype, 				    SipUri transferto )    {	SipTransaction trans = new SipTransaction( lastseq++, member, this );	transactions.add( trans );	// Send the request	trans.sendRequest( meth, body, bodytype, transferto );		// Audit the call	auditCall();		// Return the transaction object for tracking	return trans;    }      /**   * Sends a SIP register under this call to the given call member.    * Returns a SipTransaction for tracking.   */    public SipTransaction newRegister( SipUri registerserver, boolean clear ) {	return newRegister( registerserver, clear, null, null, null, null );    }    public SipTransaction newRegister( SipUri registerserver, boolean clear, 				       String authentication, 				       String proxyauthentication, 				       String body, MimeContentType bodytype )    {	localuri.setTag( null );	SipTransaction trans = new SipTransaction( lastseq++, new SipCallMember( this, localuri ), this );	transactions.add( trans );		trans.sendRegister( registerserver, clear, authentication, proxyauthentication, body, bodytype );		return trans;    }  /**   * Returns an iterator for the list of all current members of this call.   *   * @return SipCallMemberIterator   */  public ArrayList getMemberList()  { return members; }  /**   * Triggered whenever the call status changes.   */  public void callStatusUpdated() {}  /**   * Triggered whenever the call subject changes.   */  public void subjectChanged() {}  /**   * auditCall   */  private void auditCall()  {    boolean foundmemb = false;        // If there are no active call members, set the call status to 'Dead'    for( ListIterator li = members.listIterator(); li.hasNext(); ) {      SipCallMember memb = (SipCallMember)li.next();      if( ( memb.getStatus() != SipCallMember.Disconnecting ) &&	  ( memb.getStatus() != SipCallMember.Disconnected ) ) {	foundmemb = true;      }    }    if( !foundmemb ) {      callstatus = Dead;      callStatusUpdated();    }  }  /**   * incomingRequest   * @param message   * @return SipCallMember*   */  private SipCallMember incomingRequest(SipMessage message)  {      SipUri incominguri = new SipUri( message.getHeaderData( SipHeader.From ) );      String cseq = message.getHeaderData( SipHeader.CSeq );      String snum = cseq.substring( 0, cseq.indexOf(" ") );      int seqnum = 0;      SipTransaction curtrans = null;      try {	  seqnum = Integer.parseInt(snum);      } catch (NumberFormatException nfe) {	  System.err.println("Error parsing sequence number: [" + snum + "]. set to 0");      }      if (SipClient.DEBUG) System.out.println( "SipCall: Incoming request" );      // check first to see if we've already received this message      for( ListIterator li = transactions.listIterator(); li.hasNext(); ) {	  curtrans = (SipTransaction)li.next();	  if( ( incominguri.equals( curtrans.getCallMember().getUri() ) ) && ( seqnum == curtrans.getSeqNum() ) &&	      ( curtrans.getDirection() == SipTransaction.RemoteRequest ) ) {	      if (SipClient.DEBUG) System.out.println( "SipCall: Request is a retransmission, ignoring" );	      return null;	  }      }            // Update our identity if necessary      SipUri touri = new SipUri( message.getHeaderData( SipHeader.To ) );       if( touri != localuri ) {	  localuri = touri;	  if( !localuri.hasTag() ) {	      localuri.generateTag();	  }      }            if( ( message.getMethod() == Sip.ACK ) || 	  ( message.getMethod() == Sip.CANCEL ) ) 	  {	  for ( ListIterator transli = transactions.listIterator(); transli.hasNext(); )	      {		  curtrans = (SipTransaction)transli.next();	      		  if (SipClient.DEBUG) System.out.println("Found transaction with CSeq of " + curtrans.getCSeq() );		  if( ( incominguri.equals( curtrans.getCallMember().getUri() ) ) && ( seqnum == curtrans.getSeqNum() ) &&		      ( curtrans.getDirection() == SipTransaction.RemoteRequest ) ) {		      curtrans.incomingRequest( message );		      return null;		  }	      }	  if (SipClient.DEBUG) System.out.println( "SipCall: ACK/CANCEL recieved, but no matching transaction found\n" );	  return null;	  }            // took dup check out here            // Find or create a member for this request      SipCallMember  member = getMember( incominguri );      if ( member == null ) {	  member = new SipCallMember( this, incominguri );      }            // Update the Contact for this member      if( message.getContactList().getListLength() > 0 ) {	  member.setContactUri( message.getContactList().getHead() );      }      // Update the route      if( message.getRecordRoute().getListLength() > 0 ) {	  hasrecordroute = true;	  recordroute = message.getRecordRoute();	  	  hasroute = true;	  route = recordroute;	  route.addToEnd( member.getContactUri() );      }            // Create a new transaction and process it      if (SipClient.DEBUG) System.out.println( "SipCall: New transaction created" );      SipTransaction  transaction = new SipTransaction( seqnum, member, this );      transactions.add( transaction );      transaction.incomingRequest( message );            // Update member status based on this transaction      member.incomingTransaction( transaction );            return member;  }    /**     * incomingResponse     * @param message     */    private void incomingResponse(SipMessage message)    {	SipUri incominguri = new SipUri( message.getHeaderData( SipHeader.To ) );  // *** LOOK AT *** message.getRequestUri?	String cseq = message.getHeaderData( SipHeader.CSeq );	String snum = cseq.substring( 0, cseq.indexOf(" ") );	int seqnum = 0;	try {	    seqnum = Integer.parseInt(snum);	} catch (NumberFormatException nfe) {	    System.err.println("Error parsing sequence number. set to 0");	}	if (SipClient.DEBUG) System.out.println( "SipCall: Incoming response" );		SipTransaction  curtrans;	for ( ListIterator li = transactions.listIterator(); li.hasNext(); ) {	    curtrans = (SipTransaction)li.next();	    if ( ( incominguri.equals( curtrans.getCallMember().getUri() ) )		 && ( seqnum == curtrans.getSeqNum() )		 && ( curtrans.getDirection() == SipTransaction.LocalRequest ) ) {				SipCallMember  member = getMember( incominguri );		if( member == null ) {		    System.out.println( "SipCall: Billy, you really messed something up\n" );		} else if( message.getStatus().getCode() == 200 ) {		    		    if (SipClient.DEBUG) System.out.println( "SipCall: Checking for Contact and Record-Route\n" );				// Update the Contact for this member		    if( message.getContactList().getListLength() > 0 ) {			if (SipClient.DEBUG) System.out.println( "SipCall: Setting Contact for this Call Member\n" );			member.setContactUri( message.getContactList().getHead() );		    }		    				// Update the route		    if( message.getRecordRoute().getListLength() > 0 ) {			hasroute = true;			route = message.getRecordRoute();			route.reverseList();			route.addToEnd( member.getContactUri() );		    }		}				curtrans.incomingResponse( message );		return;	    }	}	if (SipClient.DEBUG) System.out.println( "SipCall: Response dropped: No transaction found\n" );    }        /**     * sendRequest   * @param reqmsg   * @param contact   */    void sendRequest(SipMessage reqmsg) {	sendRequest(reqmsg, true);    }        void sendRequest(SipMessage reqmsg, boolean contact)    {      if ( reqmsg.getMethod() == Sip.MESSAGE ) {	  //	  localuri.setProtocolName( "im" );      }            reqmsg.insertHeader( SipHeader.From, localuri.nameAddr() );      reqmsg.insertHeader( SipHeader.Call_ID, callid );            if( ( reqmsg.getMethod() == Sip.INVITE ) || ( reqmsg.getMethod() == Sip.MESSAGE ) ) {	  reqmsg.insertHeader( SipHeader.Subject, getSubject() );      }            if( hasroute ) {	  reqmsg.setRequestUri( route.getHead() );	  	  SipUriList routewithouthead = route;	  routewithouthead.removeHead();	  	  reqmsg.insertHeader( SipHeader.Route, routewithouthead.getUriList() );      }            parent.sendRequest( reqmsg, contact );  }        void sendResponse(SipMessage responsemsg) {	sendResponse(responsemsg, true);    }  /**   * sendResponse   * @param responsemsg   * @param contact   */  private void sendResponse(SipMessage responsemsg, boolean contact)  {    responsemsg.insertHeader( SipHeader.Call_ID, callid );    responsemsg.insertHeader( SipHeader.To, localuri.nameAddr() );    if( hasrecordroute ) {      responsemsg.setRecordRoute( recordroute );    }    parent.sendResponse( responsemsg, contact );  }  /**   * sendRaw   * @param msg   */  void sendRaw(SipMessage msg)  {    parent.sendRaw( msg );  }  /**   * incomingMessage   * @param message   * @return SipCallMember*   */  SipCallMember incomingMessage(SipMessage message)  {      if( message.getType() == SipMessage.Request ) {	  return incomingRequest( message );      } else if( message.getType() == SipMessage.Response ) {	  incomingResponse( message );      } else {	  if (SipClient.DEBUG) System.out.println( "SipCall: Incoming message dropped (bad message type)" );      }      return null;  }  /**   * addMember   * @param newmember   */    void addMember(SipCallMember newmember)    {	members.add( newmember );    }    /**      * statusUpdated - do this for now     */    public static void statusUpdated()    {}  // class variables  static final int StandardCall = 0;  static final int OptionsCall = 1;  static final int RegisterCall = 2;  static final int MessageCall = 3;  static final int BrokenCall = 4;  static final int UnknownCall = 5;    static final int Unconnected = 0;  static final int InviteRequested = 1;  static final int RequestingInvite = 2;  static final int InProgress = 3;  static final int Dead = 4;    private SipClient parent;  private SipUri localuri;  private ArrayList members;  private ArrayList transactions;  private int lastremoteseq;  private static int lastseq = 0;  private int calltype;  private int callstatus;  private String callid;  private String subject;  private boolean hasrecordroute;  private SipUriList recordroute;  private boolean hasroute;  private SipUriList route;}

⌨️ 快捷键说明

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