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

TestSipClientConnection

public class TestSipClientConnection extends com.sun.midp.i3test.TestCase
Tests for SipConnection class.

Fields Summary
private String
corrURI
URI of other side of SIP session.
private static final String
toTag
Server tag.
private boolean
isDialogCreated
Flag of creating a dialog.
private int
refreshID
Refresh ID for refreshable requests.
Constructors Summary
Methods Summary
voidTest1(java.lang.String method, java.lang.String transport)
Body of the test 1. Walk along states of SipClientConnection object.

param
method string representation of the requests method
param
transport the name of transport protocol


                                   
         
        /** Client connection. */
        SipClientConnection sc = null;
	StubSipRefreshListener refreshListener = null;
	
	/**
	 * Dialog is created in case of INVITE method (RFC 3261, 12.1)
	 * or SUBSCRIBE method (RFC 3265, 3.3.4) after provisional requests.
	 */
	isDialogCreated = method.equals("INVITE") || 
	    method.equals("SUBSCRIBE");
        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);
        }
        assertNotNull("sc is null", sc);
	
	// State of client connection must be "Created"
	assertEquals("State is not CREATED", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.CREATED);
	
	// Check the CREATED state
	checkCreatedState(sc);
	
	// Move to INITIALIZED state
	try {
	    sc.initRequest(method, null);
	    refreshListener = new StubSipRefreshListener();
	    refreshID = sc.enableRefresh(refreshListener);
            sc.setHeader("Content-Type", "text/plain");

	    // SUBSCRIBE request - Event header is mandatory (RFC 3265, 7.2)
	    if (method.equals("SUBSCRIBE")) {
		sc.setHeader("Event", "12345");
	    }

	} catch (Throwable e) {
            fail("INITIALIZED " +e +" was caused");
	}
	
	assertEquals("State is not INITIALIZED", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.INITIALIZED);
	
	// Check the INITIALIZED state after CREATED state
	checkInitializedState(sc, SipClientConnectionImpl.CREATED);
	
	// Move to STREAM_OPEN state
	String msg = "SipClientConnection class testing.";
	OutputStream os = null;
	try {
            sc.setHeader("Content-Length", Integer.toString(msg.length()));
            os = sc.openContentOutputStream();
        } catch (Throwable e) {
            fail("STREAM " +e +" was caused");
	}
	
	assertEquals("State is not STREAM_OPEN", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.STREAM_OPEN);
	
	// Check the STREAM_OPEN state
	checkStreamOpenState(sc, false);
        
	// write a message
	try {
	    os.write(msg.getBytes());
        } catch (Throwable e) {
            fail("write a message " +e +" was caused");
	}
        
	// Move to PROCEEDING state
	try {
	    os.close(); // close stream and send the message
        } catch (Throwable e) {
            fail("PROCEEDING " +e +" was caused");
	}
	
	assertEquals("State is not PROCEEDING", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.PROCEEDING);
	
	// check PROCEEDING state before and after provisional response
	checkComplexProceedingState(sc, method);
	
	// Move to COMPLETED state
        sendResponse(sc, Response.OK);
       
	assertEquals("State is not COMPLETED", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.COMPLETED);
	
	// Check the COMPLETED state
        if (!method.equals("INVITE")) {
	    // Transaction instanse must be in completed state
	    // (RFC 3261, 17.1.4)
	    checkCompletedState(sc, isDialogCreated, 
		Transaction.TERMINATED_STATE, Transaction.COMPLETED_STATE);
	} else {
	    // Transaction instanse must be in terminated state
	    // (RFC 3261, 17.1.1.2)
	    checkCompletedState(sc, true, Transaction.TERMINATED_STATE,
	    Transaction.TERMINATED_STATE);
	    // move to INITIALIZED state by init ACK
            Request request = null;
            CallIdHeader callIdHeader = null;
            FromHeader fromHeader = null;
            URI requestURI = null;
            ToHeader toHeader = null;
            try {
                 
                /**
                 * RFC 3261, 17.1.1.3:
                 * The ACK request constructed by the client transaction 
                 * MUST contain values for the Call-ID, From, 
                 * and Request-URI that are equal to the values of 
                 * those header fields in the request
                 */
                // save previous request data
                request = ((SipClientConnectionImpl)sc).getRequest();
                callIdHeader = request.getCallId();
                fromHeader = request.getFromHeader();
                requestURI = request.getRequestURI();
	        sc.initAck();
                // get the ACK request
                request = ((SipClientConnectionImpl)sc).getRequest();
                toHeader = request.getTo();
                assertTrue("ACK: callId is wrong", 
                    callIdHeader.toString().equals(
                    request.getCallId().toString()));
                assertTrue("ACK: From header is wrong", 
                    fromHeader.toString().equals(
                    request.getFromHeader().toString()));
                assertTrue("ACK: requestURI is wrong", 
                    requestURI.toString().equals(
                    request.getRequestURI().toString()));
                /**
                 * RFC 3261, 17.1.1.3:
                 * The To header field in the ACK MUST equal 
                 * the To header field in the response being acknowledged.
                 */
                Address toAddress = StackConnector
                    .addressFactory.createAddress(corrURI);
                ToHeader toHeader1 = StackConnector
                        .headerFactory.createToHeader(
                        toAddress, null);
                toHeader1.setTag(toTag);
                assertTrue("ACK: To header is wrong", 
                    toHeader.toString().equals(toHeader1.toString()));
	    } catch (Throwable e) {
	        fail("Exception was caused");
	    }
	
            assertEquals("State is not INITIALIZED", 
	        ((SipClientConnectionImpl)sc).getState(),
	        SipClientConnectionImpl.INITIALIZED);
		
	    // return to COMPLETED state by sending ACK
	    try {
	        sc.send();
	    } catch (Throwable e) {
	        fail("Exception was caused");
	    }
            
	    
	} 
	
	assertEquals("State is not COMPLETED", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.COMPLETED);
	
    // close connection
	try {
	    sc.close();
        } catch (Throwable e) {
            fail("" +e +" was caused");
	}
	
	assertEquals("State is not TERMINATED", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.TERMINATED);
    
	
private voidcheckCompletedState(SipClientConnection sc, boolean isDialogVisible, int transactionStateReliable, int transactionStateUnReliable)
Check the state COMPLETED of SipClientConnection object.

param
sc SipClientConnection object in COMPLETED state
param
isDialogVisible true when dialog is visible, else - false
param
transactionStateReliable client tramsaction state for reliable protocols
param
transactionStateUnReliable client tramsaction state for unreliable protocols

	
	// enableRefresh:
        disMethod_enableRefresh(sc);
	
	// initCancel:
	disMethod_initCancel(sc);
	
	// initRequest:
	disMethod_initRequest(sc);
	
	// setCredentials:
	disMethod_setCredentials(sc);
	
	// setRequestURI:
	disMethod_setRequestURI(sc);
	
	// addHeader:
	disMethod_addHeader(sc);
	
	// openContentOutputStream:
	disMethod_openContentOutputStream(sc);
	
	// removeHeader:
	disMethod_removeHeader(sc);
	
	// send:
	disMethod_send(sc);
	
	// setHeader:
	disMethod_setHeader(sc);
	    
	if (!isDialogVisible) { // dialog must be null
	    assertTrue("Dialog object is visible on COMPLETED state",
	        sc.getDialog() == null);
	} else { // check state
	    // Dialog must be visible and be in confirmed state
	    SipDialog dialog = sc.getDialog();
	    assertTrue("Dialog object is not visible on COMPLETED state",
	        dialog != null);
	    assertTrue("Completed - Dialog has wrong state", 
	        (int)dialog.getState() == SipDialog.CONFIRMED);
	}
	
	// Check client transaction
	ClientTransaction clientTransaction = 
	    ((SipClientConnectionImpl)sc).getClientTransaction();
	assertTrue("Client transaction is null on COMPLETED state",
	    clientTransaction != null);
	assertTrue("COMPLETED: Client transaction has wrong state",
	    clientTransaction.isReliable() ? 
	    clientTransaction.getState() == transactionStateReliable :
	    clientTransaction.getState() == transactionStateUnReliable);
    
private voidcheckComplexProceedingState(SipClientConnection sc, java.lang.String method)
Complex check the PROCEEDing state (before and after provisional response.

param
sc SipClientConnection object in CREATED state
param
method the method of request

	
	// Check the PROCEEDING state
	// no provisional request - dialog must be unvisible
	// (RFC 3261, 12.1)
        if (method.equals("INVITE")) {
	    // INVITE: transaction instanse must be in calling state
	    // (RFC 3261, 17.1.1.2)
	    checkProceedingState(sc, false, 0, Transaction.CALLING_STATE);
	} else {
	    // non-INVITE: transaction instanse must be in trying state
	    // (RFC 3261, 17.1.4)
	    checkProceedingState(sc, false, 0, Transaction.TRYING_STATE);
	}
	// Receiving provisional response
	sendResponse(sc, Response.TRYING);
	
	assertEquals("State is not PROCEEDING", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.PROCEEDING);
	
	// Check the PROCEEDING state
	// provisional request - dialog must be in early state
	// (JSR180)
	// Transaction instanse must be in proceeding state
	// (RFC 3261, 17.1.1.2, 17.1.4)
	checkProceedingState(sc, isDialogCreated,
	    SipDialog.EARLY, Transaction.PROCEEDING_STATE);

	// Receiving any provisional response when transaction is in
	// proceedin state doesn't change its state (both INVITE
	// and non-INVITE, RFC3261, 17.1.1.2, 17.1.4)
	sendResponse(sc, Response.TRYING);
	assertEquals("State is not PROCEEDING", 
	    ((SipClientConnectionImpl)sc).getState(),
	    SipClientConnectionImpl.PROCEEDING);
	checkProceedingState(sc, isDialogCreated,
	    SipDialog.EARLY, Transaction.PROCEEDING_STATE);

    // Move to UNAUTHORIZED state
        sendResponse(sc, Response.UNAUTHORIZED);
    
    assertEquals("State is not UNAUTHORIZED", 
        ((SipClientConnectionImpl)sc).getState(),
        SipClientConnectionImpl.UNAUTHORIZED);
    
    // Check the UNAUTHORIZED state
    checkUnautorizedState(sc);
    
    // Move to back to PROCEEDING state
    try {
        sc.setCredentials("name", "pass", "realm"); // re-send request
        } catch (Throwable e) {
            fail("" +e +" was caused");
    }
    
    
    assertEquals("State is not PROCEEDING", 
        ((SipClientConnectionImpl)sc).getState(),
        SipClientConnectionImpl.PROCEEDING);

    
private voidcheckCreatedState(SipClientConnection sc)
Check the state CREATED of SipClientConnection object.

param
sc SipClientConnection object in CREATED state

	// Try to call methods other that initRequest and setListener
	
	// enableRefresh:
        disMethod_enableRefresh(sc);
	
	// initAck:
        disMethod_initAck(sc);
	
	// initCancel:
	disMethod_initCancel(sc);
	
	// receive:
        disMethod_receive(sc);
	
	// setCredentials:
	disMethod_setCredentials(sc);
	
	// setRequestURI:
	disMethod_setRequestURI(sc);
	
	// addHeader:
	disMethod_addHeader(sc);
	
	// openContentInputStream:
	disMethod_openContentInputStream(sc);
	
	// openContentOutputStream:
	disMethod_openContentOutputStream(sc);
	
	// removeHeader:
	disMethod_removeHeader(sc);
	
	// send:
	disMethod_send(sc);
	
	// setHeader:
	disMethod_setHeader(sc);
	
	// Dialog must be unaccessable
	assertTrue("Dialog object is visible on CREATED state",
	    sc.getDialog() == null);
	    
	// Client transaction must be null
	assertTrue("Client transaction is not null on CREATED state",
	    ((SipClientConnectionImpl)sc).getClientTransaction() == null);
    
private voidcheckInitializedState(SipClientConnection sc, int prevState)
Check the state INITIALIZED of SipClientConnection object.

param
sc SipClientConnection object in INITIALIZED state
param
prevState the previous state

	
	// initAck:
        disMethod_initAck(sc);
	
	// initCancel:
	disMethod_initCancel(sc);
	
	// initRequest:
	disMethod_initRequest(sc);
	
	// receive:
        disMethod_receive(sc);
	
	// openContentInputStream:
	disMethod_openContentInputStream(sc);
	
	// Check dialog and transaction
	if (prevState == SipClientConnectionImpl.CREATED) {
	    // Dialog must be unaccessable
	    assertTrue("Dialog object is visible on INITIALIZED state",
	        sc.getDialog() == null);
	    
	    // Client transaction must be null
	    assertTrue("Client transaction is not null on INITIALIZED state",
	        ((SipClientConnectionImpl)sc).getClientTransaction() == null);
	}
    
private voidcheckProceedingState(SipClientConnection sc, boolean isDialogVisible, int dialogState, int transState)
Check the state PROCEEDING of SipClientConnection object.

param
sc SipClientConnection object in CREATED state
param
isDialogVisible true when dialog is visible, else - false
param
dialogState required state of Dialog object
param
transState required state of Transaction object

	
	// enableRefresh:
        disMethod_enableRefresh(sc);
	
	// initAck:
        disMethod_initAck(sc);
	
	// initRequest:
	disMethod_initRequest(sc);
	
	// setCredentials:
	disMethod_setCredentials(sc);
	
	// setRequestURI:
	disMethod_setRequestURI(sc);
	
	// addHeader:
	disMethod_addHeader(sc);
	
	// openContentOutputStream:
	disMethod_openContentOutputStream(sc);
	
	// removeHeader:
	disMethod_removeHeader(sc);
	
	// send:
	disMethod_send(sc);
	
	// setHeader:
	disMethod_setHeader(sc);
    	
	// Check dialog state
	if (!isDialogVisible) { // dialog must be null
	    assertTrue("Dialog object is visible on PROCEEDING state",
	        sc.getDialog() == null);
	} else { // check state
	    SipDialog dialog = sc.getDialog();
	    assertTrue("Dialog object is not visible on PROCEEDING state",
	        dialog != null);
	    assertTrue("Proceeding - Dialog has wrong state", 
	        (int)dialog.getState() == dialogState);
	}
	    
	// Check client transaction
	ClientTransaction clientTransaction = 
	    ((SipClientConnectionImpl)sc).getClientTransaction();
	assertTrue("Client transaction is null on PROCEEDING state",
	    clientTransaction != null);
	assertTrue("Client transaction has wrong state",
	    clientTransaction.getState() == transState);
    
private voidcheckStreamOpenState(SipClientConnection sc, boolean isDialog)
Check the state STREAM_OPEN of SipClientConnection object.

param
sc SipClientConnection object in STREAM_OPEN state
param
isDialog true when dialog is created, else - false

	
	// enableRefresh:
        disMethod_enableRefresh(sc);
	
	// initAck:
        disMethod_initAck(sc);
	
	// initCancel:
	disMethod_initCancel(sc);
	
	// initRequest:
	disMethod_initRequest(sc);
	
	// receive:
        disMethod_receive(sc);
	
	// setCredentials:
	disMethod_setCredentials(sc);
	
	// setRequestURI:
	disMethod_setRequestURI(sc);
	
	// addHeader:
	disMethod_addHeader(sc);
	
	// openContentInputStream:
	disMethod_openContentInputStream(sc);
	
	// openContentOutputStream:
	disMethod_openContentOutputStream(sc);
	
	// removeHeader:
	disMethod_removeHeader(sc);
	
	// setHeader:
	disMethod_setHeader(sc);
    	
	// Check dialog and transaction
	if (!isDialog) {
	    // Dialog must be unaccessable
	    assertTrue("Dialog object is visible on STREAM_OPEN state",
	        sc.getDialog() == null);
	    
	    // Client transaction must be null
	    assertTrue("Client transaction is not null on STREAM_OPEN state",
	        ((SipClientConnectionImpl)sc).getClientTransaction() == null);
	}

    
private voidcheckUnautorizedState(SipClientConnection sc)
Check the state UNAUTHORIZED of SipClientConnection object.

param
sc SipClientConnection object in UNAUTHORIZED state

	// Try to call methods other that initRequest and setListener
	
	// enableRefresh:
        disMethod_enableRefresh(sc);
	
	// initAck:
        disMethod_initAck(sc);
	
	// initCancel:
	disMethod_initCancel(sc);
	
	// initRequest:
	disMethod_initRequest(sc);
	
	// receive:
        disMethod_receive(sc);
	
	// setRequestURI:
	disMethod_setRequestURI(sc);
	
	// addHeader:
	disMethod_addHeader(sc);
	
	// openContentInputStream:
	disMethod_openContentInputStream(sc);
	
	// openContentOutputStream:
	disMethod_openContentOutputStream(sc);
	
	// removeHeader:
	disMethod_removeHeader(sc);
	
	// send:
	disMethod_send(sc);
	
	// setHeader:
	disMethod_setHeader(sc);
	    
	// Dialog must be unvisible (terminated state)    
	assertTrue("Dialog object must be unvisible on UNAUTHORIZED state",
	    sc.getDialog() == null);
    
private voiddisMethod_addHeader(SipClientConnection sc)
Disabled method addHeader.

param
sc input SipClientConnection object

	try {
	    sc.addHeader("name", "value");
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_enableRefresh(SipClientConnection sc)
Disabled method enableRefresh.

param
sc input SipClientConnection object

	StubSipRefreshListener refresh = new StubSipRefreshListener();
	try {
	    sc.enableRefresh(refresh);
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_initAck(SipClientConnection sc)
Disabled method initAck.

param
sc input SipClientConnection object

	try {
	    sc.initAck();
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_initCancel(SipClientConnection sc)
Disabled method initCancel.

param
sc input SipClientConnection object

	try {
	    sc.initCancel();
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_initRequest(SipClientConnection sc)
Disabled method initRequest.

param
sc input SipClientConnection object

	try {
	    sc.initRequest("MESSAGE", null);
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_openContentInputStream(SipClientConnection sc)
Disabled method openContentInputStream.

param
sc input SipClientConnection object

	try {
	    sc.openContentInputStream();
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_openContentOutputStream(SipClientConnection sc)
Disabled method openContentOutputStream.

param
sc input SipClientConnection object

	try {
	    sc.openContentOutputStream();
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_receive(SipClientConnection sc)
Disabled method receive.

param
sc input SipClientConnection object

	try {
	    sc.receive(10000);
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_removeHeader(SipClientConnection sc)
Disabled method removeHeader.

param
sc input SipClientConnection object

	try {
	    sc.removeHeader("Header");
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_send(SipClientConnection sc)
Disabled method send.

param
sc input SipClientConnection object

	try {
	    sc.send();
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_setCredentials(SipClientConnection sc)
Disabled method setCredentials.

param
sc input SipClientConnection object

	try {
	    sc.setCredentials("name", "password", "realm");
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_setHeader(SipClientConnection sc)
Disabled method setHeader.

param
sc input SipClientConnection object

	try {
	    sc.setHeader("Header", "value");
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
private voiddisMethod_setRequestURI(SipClientConnection sc)
Disabled method setRequestURI.

param
sc input SipClientConnection object

	try {
	    sc.setRequestURI("sip:sippy.tester@localhost:5060");
	    fail("No SipException was caused");
	} catch (SipException e) {
	    assertEquals("Wrong error code", e.getErrorCode(),
	        SipException.INVALID_STATE);
	} catch (Throwable e) {
	    fail("Wrong exception was caused");
	}
    
public voidrunTests()
Tests execute

        String arrProt[] = {"UDP", "TCP"};
        String arrMethods[] = {"INVITE", "MESSAGE", "SUBSCRIBE",
            "OPTIONS", "REGISTER", "INFO", "PUBLISH"};
        for (int i = 0; i < arrMethods.length; i++) {
            declare("SipClientConnection - " + arrMethods[i]);
            for (int j = 0; j < arrProt.length; j++) {
                Test1(arrMethods[i], arrProt[j]);
            }
        }
    
private voidsendResponse(SipClientConnection sc, int respCode)
Send a response with given code.

param
sc SipClientConnection object
param
respCode response code

	
	// 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)) {
		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);
            }
	    
            if (respCode == Response.UNAUTHORIZED) {
	        WWWAuthenticateHeader authHeader = new WWWAuthenticateHeader();
		authHeader.setParameter(AuthenticationHeader.REALM, "realm");
	        response.setHeader(authHeader);
	    }
            
            // 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");
	}