package examples.tpcc; import javax.sip.*; import javax.sip.address.*; import javax.sip.header.*; import javax.sip.message.*; import java.util.*; /** * This class is a UAC template. Shootist is the guy that shoots and shootmeA is * the guy that gets shot. * * @author M. Ranganathan */ /* * KMC - SHOOTMEA IS EXACTLY THE SAME TO THE CLASIC SHOOTME , ONLY LISTENING ON * PORT 5070 */ public class Phone implements SipListener { private static AddressFactory addressFactory; private static MessageFactory messageFactory; private static HeaderFactory headerFactory; private static SipStack sipStack; SipProvider sipProvider; private static final String myAddress = "127.0.0.1"; private static int myPort; protected ServerTransaction inviteTid; private Response okResponse; private Request inviteRequest; private Dialog dialog; private String transport = "udp"; class MyTimerTask extends TimerTask { Phone shootmeA; boolean byebye; public MyTimerTask(Phone shootmeA, boolean flag) { this.shootmeA = shootmeA; this.byebye = flag; } public void run() { if (byebye) { shootmeA.sendBye();// create a bye } else { shootmeA.sendInviteOK(); } } } protected static final String usageString = "java " + "examples.shootist.Shootist \n" + ">>>> is your class path set to the root?"; private static void usage() { System.out.println(usageString); System.exit(0); } public void processRequest(RequestEvent requestEvent) { Request request = requestEvent.getRequest(); ServerTransaction serverTransactionId = requestEvent .getServerTransaction(); System.out.println("\n\nRequest " + request.getMethod() + " received at " + sipStack.getStackName() + " with server transaction id " + serverTransactionId); if (request.getMethod().equals(Request.INVITE)) { processInvite(requestEvent, serverTransactionId); } else if (request.getMethod().equals(Request.ACK)) { processAck(requestEvent, serverTransactionId); } else if (request.getMethod().equals(Request.BYE)) { processBye(requestEvent, serverTransactionId); } else if (request.getMethod().equals(Request.CANCEL)) { processCancel(requestEvent, serverTransactionId); } } public void processResponse(ResponseEvent responseEvent) { } /** * Process the ACK request. Send the bye and complete the call flow. */ public void processAck(RequestEvent requestEvent, ServerTransaction serverTransaction) { System.out.println("shootmeA: got an ACK! "); System.out.println("Dialog State = " + dialog.getState()); new Timer().schedule(new MyTimerTask(this,true), 4000); } /** * Process the invite request. */ public void processInvite(RequestEvent requestEvent, ServerTransaction serverTransaction) { SipProvider sipProvider = (SipProvider) requestEvent.getSource(); Request request = requestEvent.getRequest(); try { System.out.println("shootmeA: got an Invite sending Trying"); // System.out.println("shootmeA: " + request); Response response = messageFactory.createResponse(Response.TRYING, request); ServerTransaction st = requestEvent.getServerTransaction(); if (st == null) { st = sipProvider.getNewServerTransaction(request); } dialog = st.getDialog(); st.sendResponse(response); this.okResponse = messageFactory.createResponse(Response.OK, request); Address address = addressFactory.createAddress("ShootmeA <sip:" + myAddress + ":" + myPort + ";lr" + ">"); ContactHeader contactHeader = headerFactory .createContactHeader(address); response.addHeader(contactHeader); ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); if (toHeader.getTag() == null ) { toHeader.setTag(new Integer((int) ( Math.random() * 10000) ).toString()); // Application is supposed to set. } else { System.out.println("Re-INVITE processing"); } okResponse.addHeader(contactHeader); // Create ContentTypeHeader ContentTypeHeader contentTypeHeader = headerFactory .createContentTypeHeader("application", "sdp"); String sdpData = "v=0\r\n" + "o=4855 13760799956958020 13760799956958020" + " IN IP4 129.6.55.78\r\n" + "s=mysession session\r\n" + "p=+46 8 52018010\r\n" + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n"; byte[] contents = sdpData.getBytes(); okResponse.setContent(contents, contentTypeHeader); this.inviteTid = st; this.inviteRequest = request; new Timer().schedule(new MyTimerTask(this,false), 1000); } catch (Exception ex) { ex.printStackTrace(); System.exit(0); } } private void sendBye() { try { dialog = this.inviteTid.getDialog(); if (dialog.getState() == DialogState.TERMINATED) { System.out.println("Dialog already terminated!"); return; } System.out.println("Sending BYE"); Request byeRequest = dialog.createRequest(Request.BYE); ClientTransaction ct = sipProvider .getNewClientTransaction(byeRequest); dialog.sendRequest(ct); } catch (SipException ex) { ex.printStackTrace(); } } private void sendInviteOK() { try { if (inviteTid.getState() != TransactionState.COMPLETED) { System.out.println("shootmeA: Dialog state before 200: " + inviteTid.getDialog().getState()); inviteTid.sendResponse(okResponse); System.out.println(myPort + " Dialog state after 200: " + inviteTid.getDialog().getState()); } } catch (SipException ex) { ex.printStackTrace(); } catch (InvalidArgumentException ex) { ex.printStackTrace(); } } /** * Process the bye request. */ public void processBye(RequestEvent requestEvent, ServerTransaction serverTransactionId) { SipProvider sipProvider = (SipProvider) requestEvent.getSource(); Request request = requestEvent.getRequest(); try { System.out.println(myPort + " got a bye sending OK."); Response response = messageFactory.createResponse(200, request); serverTransactionId.sendResponse(response); System.out.println("Dialog State is " + serverTransactionId.getDialog().getState()); } catch (Exception ex) { ex.printStackTrace(); System.exit(0); } } public void processCancel(RequestEvent requestEvent, ServerTransaction serverTransactionId) { SipProvider sipProvider = (SipProvider) requestEvent.getSource(); Request request = requestEvent.getRequest(); try { System.out.println("shootmeA: got a cancel."); if (serverTransactionId == null) { System.out.println("shootmeA: null tid."); return; } Response response = messageFactory.createResponse(200, request); serverTransactionId.sendResponse(response); if (dialog.getState() != DialogState.CONFIRMED) { response = messageFactory.createResponse( Response.REQUEST_TERMINATED, inviteRequest); inviteTid.sendResponse(response); } } catch (Exception ex) { ex.printStackTrace(); System.exit(0); } } public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { Transaction transaction; if (timeoutEvent.isServerTransaction()) { transaction = timeoutEvent.getServerTransaction(); } else { transaction = timeoutEvent.getClientTransaction(); } System.out.println("state = " + transaction.getState()); System.out.println("dialog = " + transaction.getDialog()); System.out.println("dialogState = " + transaction.getDialog().getState()); System.out.println("Transaction Time out"); } public void init() { SipFactory sipFactory = null; sipStack = null; sipFactory = SipFactory.getInstance(); sipFactory.setPathName("gov.nist"); Properties properties = new Properties(); properties.setProperty("javax.sip.STACK_NAME", "phone" + myPort); // You need 16 for logging traces. 32 for debug + traces. // Your code will limp at 32 but it is best for debugging. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "TRACE"); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "phone" + myPort + "debuglog.txt"); properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "phone" + myPort + "log.txt"); try { // Create SipStack object sipStack = sipFactory.createSipStack(properties); System.out.println("sipStack = " + sipStack); } catch (PeerUnavailableException e) { // could not find // gov.nist.jain.protocol.ip.sip.SipStackImpl // in the classpath e.printStackTrace(); System.err.println(e.getMessage()); if (e.getCause() != null) e.getCause().printStackTrace(); System.exit(0); } try { headerFactory = sipFactory.createHeaderFactory(); addressFactory = sipFactory.createAddressFactory(); messageFactory = sipFactory.createMessageFactory(); ListeningPoint lp = sipStack.createListeningPoint("127.0.0.1", myPort, transport); Phone listener = this; sipProvider = sipStack.createSipProvider(lp); System.out.println("provider " + sipProvider); sipProvider.addSipListener(listener); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); usage(); } } public static void main(String args[]) throws Exception { myPort = Integer.parseInt(args[0]); new Phone().init(); } public void processIOException(IOExceptionEvent exceptionEvent) { System.out.println("IOException"); } public void processTransactionTerminated( TransactionTerminatedEvent transactionTerminatedEvent) { System.out.println("Transaction terminated event recieved"); } public void processDialogTerminated( DialogTerminatedEvent dialogTerminatedEvent) { System.out.println("Dialog terminated event recieved"); } }