Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Conditions Of Use
*
* This software was developed by employees of the National Institute of
* Standards and Technology (NIST), and others.
* This software is has been contributed to the public domain.
* As a result, a formal license is not needed to use the software.
*
* This software is provided "AS IS."
* NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY. NIST does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
*
*/
package test.tck.msgflow.callflows.subsnotify;
import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.DialogState;
import javax.sip.DialogTerminatedEvent;
import javax.sip.IOExceptionEvent;
import javax.sip.ListeningPoint;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipListener;
import javax.sip.SipProvider;
import javax.sip.SipStack;
import javax.sip.Transaction;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.ContactHeader;
import javax.sip.header.EventHeader;
import javax.sip.header.ExpiresHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.SubscriptionStateHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import test.tck.TestHarness;
import test.tck.msgflow.callflows.ProtocolObjects;
import test.tck.msgflow.callflows.TestAssertion;
/**
* This is the side that sends out the notify.
*
* This code is released to domain.
*
* @author M. Ranganathan
*/
public class Notifier implements SipListener {
private static AddressFactory addressFactory;
private static MessageFactory messageFactory;
private static HeaderFactory headerFactory;
private static SipStack sipStack;
private int port;
protected SipProvider sipProvider;
protected Dialog dialog;
private String transport;
private static Logger logger = Logger.getLogger(Notifier.class) ;
private boolean gotSubscribeRequest;
static {
try {
logger.setLevel(Level.INFO);
logger.addAppender(new FileAppender(new SimpleLayout(),
"logs/notifieroutputlog.txt"));
} catch (Exception ex) {
logger.info(ex.getMessage(), ex);
TestHarness.fail("Failed to initialize Subscriber, because of " + ex.getMessage());
}
}
class MyEventSource implements Runnable {
private Notifier notifier;
private EventHeader eventHeader;
public MyEventSource(Notifier notifier, EventHeader eventHeader ) {
this.notifier = notifier;
this.eventHeader = eventHeader;
}
public void run() {
try {
for (int i = 0; i < 1; i++) {
Thread.sleep(1000);
Request request = this.notifier.dialog.createRequest(Request.NOTIFY);
SubscriptionStateHeader subscriptionState = headerFactory
.createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE);
request.addHeader(subscriptionState);
request.addHeader(eventHeader);
// Lets mark our Contact
((SipURI)dialog.getLocalParty().getURI()).setParameter("id","not2");
ClientTransaction ct = sipProvider.getNewClientTransaction(request);
logger.info("NOTIFY Branch ID " +
((ViaHeader)request.getHeader(ViaHeader.NAME)).getParameter("branch"));
this.notifier.dialog.sendRequest(ct);
logger.info("Dialog " + dialog);
logger.info("Dialog state after active NOTIFY: " + dialog.getState());
}
} catch (Throwable ex) {
logger.info(ex.getMessage(), ex);
TestHarness.fail("Failed MyEventSource.run(), because of " + ex.getMessage());
}
}
}
public void processRequest(RequestEvent requestEvent) {
Request request = requestEvent.getRequest();
ServerTransaction serverTransactionId = requestEvent
.getServerTransaction();
logger.info("\n\nRequest " + request.getMethod()
+ " received at " + sipStack.getStackName()
+ " with server transaction id " + serverTransactionId
+ " and dialog id " + requestEvent.getDialog() );
if (request.getMethod().equals(Request.SUBSCRIBE)) {
processSubscribe(requestEvent, serverTransactionId);
}
}
/**
* Process the invite request.
*/
public void processSubscribe(RequestEvent requestEvent,
ServerTransaction serverTransaction) {
SipProvider sipProvider = (SipProvider) requestEvent.getSource();
Request request = requestEvent.getRequest();
try {
logger.info("notifier: got an Subscribe sending OK");
logger.info("notifier: " + request);
logger.info("notifier : dialog = " + requestEvent.getDialog());
EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME);
this.gotSubscribeRequest = true;
AbstractSubsnotifyTestCase.assertTrue("Event header is null ", eventHeader != null);
// Always create a ServerTransaction, best as early as possible in the code
Response response = null;
ServerTransaction st = requestEvent.getServerTransaction();
if (st == null) {
st = sipProvider.getNewServerTransaction(request);
}
// Check if it is an initial SUBSCRIBE or a refresh / unsubscribe
boolean isInitial = requestEvent.getDialog() == null;
if ( isInitial ) {
// JvB: need random tags to test forking
String toTag = Integer.toHexString( (int) (Math.random() * Integer.MAX_VALUE) );
response = messageFactory.createResponse(202, request);
ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
// Sanity check: to header should not ahve a tag. Else the dialog
// should have matched
AbstractSubsnotifyTestCase.assertTrue("To tag should be null ", toHeader.getTag() == null);
toHeader.setTag(toTag); // Application is supposed to set.
this.dialog = st.getDialog();
// subscribe dialogs do not terminate on bye.
this.dialog.terminateOnBye(false);
AbstractSubsnotifyTestCase.assertTrue("initial -- dialog assigned to the transaction not null " , dialog != null );
AbstractSubsnotifyTestCase.assertTrue("Dialog state should be null ", dialog.getState() == null);
} else {
response = messageFactory.createResponse(200, request);
}
// Both 2xx response to SUBSCRIBE and NOTIFY need a Contact
Address address = addressFactory.createAddress("Notifier ");
((SipURI)address.getURI()).setPort( sipProvider.getListeningPoint(transport).getPort() );
ContactHeader contactHeader = headerFactory.createContactHeader(address);
response.addHeader(contactHeader);
// Expires header is mandatory in 2xx responses to SUBSCRIBE
ExpiresHeader expires = (ExpiresHeader) request.getHeader( ExpiresHeader.NAME );
if (expires==null) {
expires = headerFactory.createExpiresHeader(30);// rather short
}
response.addHeader( expires );
/*
* JvB: The SUBSCRIBE MUST be answered first. See RFC3265 3.1.6.2:
* "[...] a NOTIFY message is always sent immediately after any 200-
* class response to a SUBSCRIBE request"
*
* Do this before creating the NOTIFY request below
*/
st.sendResponse(response);
//Thread.sleep(1000); // Be kind to implementations
/*
* NOTIFY requests MUST contain a "Subscription-State" header with a
* value of "active", "pending", or "terminated". The "active" value
* indicates that the subscription has been accepted and has been
* authorized (in most cases; see section 5.2.). The "pending" value
* indicates that the subscription has been received, but that
* policy information is insufficient to accept or deny the
* subscription at this time. The "terminated" value indicates that
* the subscription is not active.
*/
Request notifyRequest = dialog.createRequest( "NOTIFY" );
// Mark the contact header, to check that the remote contact is updated
((SipURI)contactHeader.getAddress().getURI()).setParameter("id","not");
// Initial state is pending, second time we assume terminated (Expires==0)
SubscriptionStateHeader sstate = headerFactory.createSubscriptionStateHeader(
isInitial ? SubscriptionStateHeader.PENDING : SubscriptionStateHeader.TERMINATED );
// Need a reason for terminated
if ( sstate.getState().equalsIgnoreCase("terminated") ) {
sstate.setReasonCode( "deactivated" );
}
notifyRequest.addHeader(sstate);
notifyRequest.setHeader(eventHeader);
notifyRequest.setHeader(contactHeader);
// notifyRequest.setHeader(routeHeader);
ClientTransaction ct = sipProvider.getNewClientTransaction(notifyRequest);
// Let the other side know that the tx is pending acceptance
//
dialog.sendRequest(ct);
logger.info("NOTIFY Branch ID " +
((ViaHeader)request.getHeader(ViaHeader.NAME)).getParameter("branch"));
logger.info("Dialog " + dialog);
logger.info("Dialog state after pending NOTIFY: " + dialog.getState());
AbstractSubsnotifyTestCase.assertTrue("Dialog state after pending NOTIFY ",
dialog.getState() == DialogState.CONFIRMED);
if (isInitial) {
Thread myEventSource = new Thread(new MyEventSource(this,eventHeader));
myEventSource.start();
}
} catch (Throwable ex) {
logger.info(ex.getMessage(), ex);
TestHarness.fail("Failed to processs Subscriber, because of " + ex.getMessage());
}
}
public void processResponse(ResponseEvent responseReceivedEvent) {
Response response = (Response) responseReceivedEvent.getResponse();
Transaction tid = responseReceivedEvent.getClientTransaction();
logger.info("Response received with client transaction id "
+ tid + " CSeq = " +
response.getHeader(CSeqHeader.NAME)
+ " status code = " + response.getStatusCode() );
}
public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
Transaction transaction;
if (timeoutEvent.isServerTransaction()) {
transaction = timeoutEvent.getServerTransaction();
} else {
transaction = timeoutEvent.getClientTransaction();
}
logger.info("state = " + transaction.getState());
logger.info("dialog = " + transaction.getDialog());
logger.info("dialogState = "
+ transaction.getDialog().getState());
logger.info("Transaction Time out");
AbstractSubsnotifyTestCase.fail("Unexpected timeout event");
}
public SipProvider createProvider(int newPort) {
try {
port = newPort;
ListeningPoint lp = sipStack.createListeningPoint("127.0.0.1",
this.port, transport);
this.sipProvider = sipStack.createSipProvider(lp);
logger.info("udp provider " + sipProvider);
} catch (Exception ex) {
logger.info(ex.getMessage(), ex);
sipProvider = null;
TestHarness.fail("Failed to create SIP Provider on port " + newPort + ", because of " + ex.getMessage());
}
return sipProvider;
}
public Notifier(ProtocolObjects protObjects) {
addressFactory = protObjects.addressFactory;
messageFactory = protObjects.messageFactory;
headerFactory = protObjects.headerFactory;
sipStack = protObjects.sipStack;
transport = protObjects.transport;
}
public void processIOException(IOExceptionEvent exceptionEvent) {
// TODO Auto-generated method stub
}
public void processTransactionTerminated(
TransactionTerminatedEvent transactionTerminatedEvent) {
// TODO Auto-generated method stub
}
public void processDialogTerminated(
DialogTerminatedEvent dialogTerminatedEvent) {
// TODO Auto-generated method stub
}
public TestAssertion getAssertion() {
return new TestAssertion() {
@Override
public boolean assertCondition() {
return gotSubscribeRequest;
}
};
}
public void checkState() {
TestHarness.assertTrue("Did not see subscribe", this.gotSubscribeRequest);
}
}