Package org.cafesip.sipunit

Source Code of org.cafesip.sipunit.RegisterSession

// ========================================================================
// Copyright 2008-2009 NEXCOM Systems
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.cafesip.sipunit;

import static junit.framework.Assert.fail;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
import javax.sip.TimeoutEvent;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.address.URI;
import javax.sip.header.AuthorizationHeader;
import javax.sip.header.CallIdHeader;
import javax.sip.header.ContactHeader;
import javax.sip.header.ExpiresHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;

import org.cafesip.sipunit.SipPhone;
import org.cafesip.sipunit.SipTransaction;

public class RegisterSession extends AbstractSession
{
  protected CallIdHeader _callId;
  private int _cseq = 0;
    private Request lastRegistrationRequest;
  private static int __timeout = 5000;
 
  public RegisterSession(SipPhone phone)
  {
    super(phone);
    _callId = _sipPhone.getParent().getSipProvider().getNewCallId();
  }
 
 
    /**
     * This method is used to register with the SIP proxy server that was
     * specified when this SipPhone was created. If none was specified, the
     * REGISTER message is sent using information from this SipPhone's URI
     * (address of record). In either case, if the host is not a numeric IP
     * address (w.x.y.z), DNS will be used to resolve the host name to an
     * address.
     * <p>
     * Initially, a REGISTER message is sent without any user name and password.
     * If the server returns an OK, this method returns a true value.
     * <p>
     * If any challenge is received in response to sending the REGISTER message
     * (response code UNAUTHORIZED or PROXY_AUTHENTICATION_REQUIRED), the
     * SipPhone's credentials list is checked first for the corresponding realm
     * entry. If found, the credentials list entry username and password are
     * used to form the required authorization header for resending the REGISTER
     * message to the server, and the authorization header is saved for later
     * re-use. You can clear out saved authorization headers by calling the
     * unregister() method.
     * <p>
     * If the challenging realm is not found in the SipPhone credentials list,
     * the user parameter passed to this method is examined. If it is null, this
     * method returns false. If it is not null, the user and password values
     * passed in to this method are used to respond to the challenge. The
     * credentials list is not modified by this scenario (no entry is
     * automatically added with this user, password). Also, the authorization
     * created for this registration is not saved for re-use on a later
     * registration. IE, the user/password parameters are for a one-time,
     * single-shot use only.
     * <p>
     * After responding to the challenge(s) by resending the REGISTER message,
     * this method returns a true or false value depending on the outcome as
     * indicated by the server.
     * <p>
     * If the contact parameter is null, user@hostname is used where hostname is
     * the SipStack's IP address property which defaults to
     * InetAddress.getLocalHost().getHostAddress(), and other SipStack
     * properties also apply. Otherwise, the contact parameter given is used in
     * the Registration message sent to the server.
     * <p>
     * If the expiry parameter is 0, the registration request never expires.
     * Otherwise, the duration, given in seconds, is sent to server.
     * <p>
     * This method can be called repeatedly to update the expiry or to add new
     * contacts.
     * <p>
     * This method determines the contact information for this user agent,
     * whether the registration was successful or not. If successful, the
     * contact information may have been updated by the server (such as the
     * expiry time, if not specified to this method by the caller). Once this
     * method has been called, the test program can get information about the
     * contact for this agent by calling the *MyContact*() getter methods.
     *
     * @param user
     *            Optional - user name for authenticating with the server.
     *            Required if the server issues an authentication challenge.
     * @param password
     *            Optional - used only if the server issues an authentication
     *            challenge.
     * @param contact
     *            An URI string (ex: sip:bob@192.0.2.4), or null to use the
     *            default contact for this user agent.
     * @param expiry
     *            Expiry time in seconds, or 0 if no registration expiry.
     * @throws InvalidArgumentException
     * @throws ParseException
     */
    public Response register(String user, String password, String contact,
            int expiry)
    {
          Request request = createRegister(contact, expiry);
            return sendRegistrationMessage(request, user, password);
    }
   
    public Request createRegister( String contact, int expiry)
    {
      try
    {
      Request request = newRequest(Request.REGISTER, ++_cseq, _sipPhone.getAddress().getURI().toString());
      String host = ((SipURI) request.getRequestURI()).getHost();
      request.setRequestURI(getAddressFactory().createSipURI(null, host));
      request.setHeader(_callId);

      ContactHeader contactHeader;
      if (contact != null)
      { 
          Address contactAddr = getAddressFactory().createAddress(contact);
          if (!contactAddr.getURI().isSipURI()) {
            fail("URI " + contact + " is not a Sip URI");
          }

          contactHeader = getHeaderFactory().createContactHeader(contactAddr);
        if (contact.equals("*"))
        {
          contactHeader.setWildCard();
          request.addHeader(getHeaderFactory().createExpiresHeader(expiry));
        }
      }
      else
        contactHeader = _sipPhone.getContactInfo().getContactHeader();
 
      contactHeader.setExpires(expiry);
     
      request.addHeader(contactHeader);

      // include any auth information for this User Agent's registration
      // if any exists
      LinkedHashMap<String, AuthorizationHeader> auth_list =
        _sipPhone.getAuthorizations().get(_callId.getCallId());
      if (auth_list != null)
      {
          ArrayList<AuthorizationHeader> auth_headers = new ArrayList<AuthorizationHeader>(
                  auth_list.values());
          Iterator<AuthorizationHeader> i = auth_headers.iterator();
          while (i.hasNext())
          {
              AuthorizationHeader auth = i.next();
              request.addHeader(auth);
          }
      }
      else
      {
          // create the auth list entry for this phone's registrations
          _sipPhone.enableAuthorization(_callId.getCallId());
      }
      return request;
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
    }
   
    /**
     * This method is equivalent to the other register() method with no
     * authorization parameters passed in. Call this method if no authorization
     * will be needed or after setting up the SipPhone's credentials list.
     *
     * @param contact
     *            An URI string (ex: sip:bob@192.0.2.4)
     * @param expiry
     *            Expiry time in seconds, or 0 if no expiry.
     * @return false if registration fails or an error is encountered, true
     *         otherwise.
     */
    public Response register(String contact, int expiry)
    {
        return register(null, null, contact, expiry);
    }
   
    public Response register(int expiry)
    {
        return register(null, null, null, expiry);
    }

    /**
     * This method performs the SIP unregistration process. It returns true if
     * unregistration was successful or no unregistration was needed, and false
     * otherwise. Any authorization headers required for the last registration
     * are cleared out.
     * <p>
     * If the contact parameter is null, user@hostname is unregistered where
     * hostname is obtained by calling InetAddr.getLocalHost(). Otherwise, the
     * contact parameter value is used in the unregistration message sent to the
     * server.
     *
     * @param contact
     *            The contact URI (ex: sip:bob@192.0.2.4) to unregister.
     * @param timeout
     *            The maximum amount of time to wait for a response, in
     *            milliseconds. Use a value of 0 to wait indefinitely.
     *
     * @return true if the unregistration succeeded or no unregistration was
     *         needed, false otherwise.
     */
    public Response unregister(String contact)
    {
      return register(null, null, contact, 0);

    }
   
    public Response sendRegistrationMessage(Request request, String user,
            String password)
    {
      return sendRegistrationMessage(request, user, password, Response.OK);
    }
 
    public Response sendRegistrationMessage(Request request, int expectedResponseCode)
    {
      return sendRegistrationMessage(request, null, null, expectedResponseCode);
    }
   
    public Response sendRegistrationMessage(Request request, String user,
              String password, int expectedResponseCode)
      {
        SipTransaction trans = _sipPhone.sendRequestWithTransaction(request, true, null);

        Response response = waitResponse(trans);
        int status_code = response.getStatusCode();

        while (status_code != expectedResponseCode)
        {
            if (status_code == Response.TRYING)
            {
                response = waitResponse(trans);
                status_code = response.getStatusCode();
            }
            else if ((status_code == Response.UNAUTHORIZED)
                    || (status_code == Response.PROXY_AUTHENTICATION_REQUIRED))
            {
                // modify the request to include user authorization info
                request = _sipPhone.processAuthChallenge(response, request, user, password);
                if (request == null)
                    return null;

                _cseq++;
                // clean up last transaction
                _sipPhone.clearTransaction(trans);

                // send the request again
                trans = _sipPhone.sendRequestWithTransaction(request, true, null);

                response = waitResponse(trans);
                status_code = response.getStatusCode();
            }
            else
            {
                fail("The status code " + status_code + " " + response.getReasonPhrase() +
                    " was received from the server when expected " + expectedResponseCode);
            }
        }

        lastRegistrationRequest = request;

        return response;
    }
       
    /**
     * This method returns the request sent at the last successful registration.
     *
     * @return Returns the lastRegistrationRequest.
     */
    protected Request getLastRegistrationRequest()
    {
        return lastRegistrationRequest;
    }
   
    public boolean isRegistered()
    {
      if (lastRegistrationRequest == null)
        return false;
      ContactHeader contact = (ContactHeader) lastRegistrationRequest.getHeader(ContactHeader.NAME);
      if (contact != null)
        return contact.getExpires() != 0;
      ExpiresHeader expires = lastRegistrationRequest.getExpires();
      if (expires != null && expires.getExpires() == 0)
        return false;
      return true;
       
    }
   
  public int getTimeout()
  {
    return __timeout;
  }


  public static void setTimeout(int timeout)
  {
    __timeout = timeout;
  }
}
TOP

Related Classes of org.cafesip.sipunit.RegisterSession

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.