FileDocCategorySizeDatePackage
TestSipDialogClient.javaAPI DocphoneME MR2 API (J2ME)13037Wed May 02 18:00:40 BST 2007gov.nist.microedition.sip

TestSipDialogClient.java

/*
 *   
 *
 * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program 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 version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */

package gov.nist.microedition.sip;

import javax.microedition.sip.*;
import javax.microedition.io.Connector;
import gov.nist.siplite.message.Request;
import gov.nist.siplite.message.Response;
import gov.nist.siplite.address.Address;
import gov.nist.siplite.address.SipURI;
import gov.nist.siplite.header.ToHeader;
import gov.nist.siplite.header.ContactHeader;
import gov.nist.siplite.stack.ClientTransaction;
import gov.nist.siplite.SipStack;
import gov.nist.siplite.stack.SIPServerResponseInterface;
import gov.nist.siplite.stack.GetSipServerResponse;
import gov.nist.core.ParseException;
import gov.nist.siplite.header.ExpiresHeader;
import com.sun.midp.i3test.TestCase;
/**
 * Tests for SipConnection class.
 *
 */
public class TestSipDialogClient extends TestCase {
    
    /** URI of other side of SIP session. */
    private String corrURI = "sip:sippy.tester@localhost:5060";
    
    /** Refresh ID for refreshable requests. */
    private int refreshID = 0;
    
    /** Server tag. */
    private static final String toTag = StackConnector.generateTag();

    /**
     * Body of the test 1.
     *
     * INVITE request - walk along states of SipDialog object.
     * @param transport the name of transport protocol
     */
    void Test1(String transport) {
        /** Client connection. */
        SipClientConnection sc = null;
        StubSipRefreshListener refreshListener = null;

        // create a dialog
		try {
            // Open SIP client connection to the local SIP server
            sc = (SipClientConnection) 
	        Connector.open(corrURI + ";transport=" + transport);
        } catch (Exception ex) {
            assertNull("Exception during sc open", sc);
        }

        // Dialog instance is not visible (no provisional respomse)
        // (JSR180, 1.0.1, p. 42)
        assertTrue("Dialog is visible on initialization", 
            sc.getDialog() == null);
       
        // Move to EARLY state
        try {
            sc.initRequest("INVITE", null);
            refreshListener = new StubSipRefreshListener();
            refreshID = sc.enableRefresh(refreshListener);
            sc.send(); // send a message
            // Receiving provisional response
            sendResponse(sc, Response.TRYING);
        } catch (Exception ex) {
            fail("Exception during moving to EARLY state");
        }

        // dialog must be visible
        SipDialog testDialog = sc.getDialog();
        assertTrue("Dialog is null", testDialog != null);
        // dialog must be in EARLY state
        assertTrue("Dialog instance has wrong state", 
	        testDialog.getState() == SipDialog.EARLY);

        // Move to CONFIRMED state
        sendResponse(sc, Response.OK);
        // dialog must be visible
        testDialog = sc.getDialog();
        assertTrue("Dialog is null", testDialog != null);
        // dialog must be in CONFIRMED state
        assertTrue("Dialog instance has wrong state", 
        testDialog.getState() == SipDialog.CONFIRMED);
        
		// close the connection
		try {
		    sc.close();
        } catch (Exception ex) {
            fail("Exception during closing SipClientConnection");
        }
        
        // Send a message inside dialog
        SipClientConnection scl = null;
        try {
            scl = testDialog.getNewClientConnection("MESSAGE");
            scl.send();
            sendResponse(scl, Response.MULTIPLE_CHOICES);
        } catch (Exception ex) {
            fail("Exception during sending request inside a dialog");
            ex.printStackTrace();
        }
        // dialog must be in CONFIRMED state
        assertTrue("Dialog instance has wrong state", 
        testDialog.getState() == SipDialog.CONFIRMED);
        
        // close the connection
        try {
            scl.close();
        } catch (Exception ex) {
            fail("Exception during closing SipClientConnection");
        }
        
        // Move to TERMINATED state
        try {
		    scl = testDialog.getNewClientConnection("BYE");
			scl.send();
            sendResponse(scl, Response.OK);
        } catch (Exception ex) {
            fail("Exception during moving to TERMINATED state");
            ex.printStackTrace();
        }
        // dialog must not be visible - see JSR180, method getDialog
        testDialog = scl.getDialog();
        assertTrue("Dialog is not null", testDialog == null);
        
        // close the connection
        try {
            scl.close();
        } catch (Exception ex) {
            fail("Exception during closing SipClientConnection");
        }
        
    }

    /**
     * Body of the test 2.
     *
     * SUBSCRIBE request - walk along states of SipDialog object.
     * @param transport the name of transport protocol
     */
    void Test2(String transport) {
        /** Client connection. */
        SipClientConnection sc = null;
        StubSipRefreshListener refreshListener = null;

        // create a dialog
        try {
            // Open SIP client connection to the local SIP server
            sc = (SipClientConnection) 
            Connector.open("sip:sippy.tester@localhost:5060;transport="
            + transport);
        } catch (Exception ex) {
            assertNull("Exception during sc open", sc);
        }

        // Dialog instance is not visible (no response)
        // (JSR180, 1.0.1, p. 42)
        assertTrue("Dialog is visible on initialization", 
            sc.getDialog() == null);
       
        // Move to EARLY state
        try {
            sc.initRequest("SUBSCRIBE", null);
            refreshListener = new StubSipRefreshListener();
            refreshID = sc.enableRefresh(refreshListener);
            // SUBSCRIBE request - Event header is mandatory (RFC 3265, 7.2)
            sc.setHeader("Event", "12345");
            sc.send(); // send a message
            sendResponse(sc, Response.TRYING);
        } catch (Exception ex) {
            fail("Exception during moving to EARLY state");
        }

        // dialog must be unvisible even after provisional response
        // (SUBSCRIBE dialog)
        assertTrue("Dialog is not visible", sc.getDialog() != null);
        assertTrue("Dialog instance has wrong state", 
        sc.getDialog().getState() == SipDialog.EARLY);

        // Move to CONFIRMED state
        sendResponse(sc, Response.OK);
        // dialog must be visible
        SipDialog testDialog = sc.getDialog();
        assertTrue("Dialog is null", testDialog != null);
        // dialog must be in CONFIRMED state
        assertTrue("Dialog instance has wrong state", 
        testDialog.getState() == SipDialog.CONFIRMED);
        
        // close the connection
        try {
            sc.close();
        } catch (Exception ex) {
            fail("Exception during closing SipClientConnection");
        }
        
        // Send a message inside dialog
        SipClientConnection scl = null;
        try {
            scl = testDialog.getNewClientConnection("MESSAGE");
            scl.send();
            sendResponse(scl, Response.MULTIPLE_CHOICES);
        } catch (Exception ex) {
            fail("Exception during sending request inside a dialog");
            ex.printStackTrace();
        }
        // dialog must be in CONFIRMED state
        assertTrue("Dialog instance has wrong state", 
        testDialog.getState() == SipDialog.CONFIRMED);
        
        // close the connection
        try {
            scl.close();
        } catch (Exception ex) {
            fail("Exception during closing SipClientConnection");
        }
        
        // Move to TERMINATED state
        try {
            scl = testDialog.getNewClientConnection("SUBSCRIBE");
            scl.setHeader("Event", "12345");
            // unsubscribe
            scl.setHeader("Expires", "0");
            scl.send();
            sendResponse(scl, Response.OK);
        } catch (Exception ex) {
            fail("Exception during moving to TERMINATED state");
            ex.printStackTrace();
        }
        // dialog must not be visible - see JSR180, method getDialog
        testDialog = scl.getDialog();
        assertTrue("Dialog is not null", testDialog == null);
        
        // close the connection
        try {
            scl.close();
        } catch (Exception ex) {
            fail("Exception during closing SipClientConnection");
        }
    }
    
    /**
     * Send a response with given code.
     *
     * @param sc SipClientConnection object
     * @param respCode response code
     */
    private void sendResponse(SipClientConnection sc, int respCode) {
	
	// Send a response
	Request request = null;
	Response response = null;
	
	try {
	    request = ((SipClientConnectionImpl)sc).getRequest();
	    // create a response for request
	    response = request.createResponse(respCode);
            
            // When response is 200 OK change "To" header (RFC 3261, 17.1.1.3)
            if (respCode == Response.OK) {
                Address toAddress = StackConnector
                    .addressFactory.createAddress(corrURI);
                ToHeader toHeader = null;
                try {
                    toHeader = StackConnector
                        .headerFactory.createToHeader(
                        toAddress, null);
                } catch (ParseException ex) {
                    fail("Problem during the creation"
                    + " of the ToHeader");
                }
                response.setTo(toHeader);
            }

        // When response is 2xx and request is refreshable,
            // response must contain "expires" header (RFC 3265, 7.1)
	    if ((respCode / 100 == 2) && (refreshID != 0) && 
            (response.getHeader("Expires") == null)) {
		ExpiresHeader expHeader = new ExpiresHeader();
		expHeader.setExpires(1000);
		response.setHeader(expHeader);
            }

            // RFC 3261 8.2.6.2 Response must have To tag
            ToHeader toHeader = response.getTo();
            if (!toHeader.hasTag()) {
                // To header has no tag - add server tag
                toHeader.setTag(toTag);
                response.setTo(toHeader);
            }
	    
            
            // add Contact header when request is not "MESSAGE"
            if ((respCode == Response.OK) && 
                (!request.getMethod().equals("MESSAGE"))) {
                SipURI contactURI = StackConnector
                            .addressFactory
                            .createSipURI("sippy.tester", // name
                            "localhost:5060");
                ContactHeader contactHeader =
                            StackConnector
                            .headerFactory
                            .createContactHeader(
                            StackConnector
                            .addressFactory
                            .createAddress(contactURI));
                response.addHeader(contactHeader);
            }
          
	    ClientTransaction clientTransaction = 
	        ((SipClientConnectionImpl)sc).getClientTransaction();
	    
	    SipStack sipStack = ((SipClientConnectionImpl)sc).getSipStack();
	    
	    SIPServerResponseInterface ssc = 
	        GetSipServerResponse.newSIPServerResponse(sipStack, response, 
		clientTransaction.getMessageChannel());
	    
	    ssc.processResponse(response, 
	        clientTransaction.getMessageChannel());
	    // receive a response
	    assertTrue("Response wasn't received", sc.receive(10000));	
	} catch (Throwable e) {
            fail("sendResponse " +e +" was caused");
	    e.printStackTrace();
	}
    }
       
    /**
     * Tests execute
     *
     */
    public void runTests() {
        String arrProt[] = {"UDP", "TCP"};
        for (int i = 0; i < arrProt.length; i++) {
            declare("SipDialog - INVITE " + arrProt[i]);
                Test1(arrProt[i]);
            declare("SipDialog - SUBSCRIBE " + arrProt[i]);
                Test2(arrProt[i]);
        }
    }

}