package examples.tpcc; import javax.sip.*; import javax.sip.address.*; import javax.sip.header.*; import javax.sip.message.*; import java.util.*; import java.text.ParseException; /** * The Click to dial third party call controller application. * * @author Kathleen McCallum * *
 *   main () -> init()
 *  init()
 *    createSipStack
 *    createInvite() -> First
 *  processResponse()
 *    if (OK) first
 *       createInvite() -> second
 *    else if (OK) second
 *       ack() -> second
 *       ack() -> first
 * 
* * * */ public class Controller implements SipListener { private static SipProvider sipProvider; private static AddressFactory addressFactory; private static MessageFactory messageFactory; private static HeaderFactory headerFactory; private static SipStack sipStack; private ContactHeader contactHeader; private ListeningPoint udpListeningPoint; protected ClientTransaction inviteFirst; protected ClientTransaction inviteSecond; String Secuencia; String transport = "udp"; protected static final String usageString = "java " + "examples.ctd.ctdControll \n" + ">>>> is your class path set to the root?"; ResponseEvent responseFirstEvent; String Auser = "AGuy"; String ASipAddressDomain = "Afirst.com"; String ADisplayName = "The A first"; String Buser = "BGuy"; String BSipAddressDomain = "BSecond.com"; String BDisplayName = "The B second"; String peerHostPortA = "127.0.0.1:5070"; String peerHostPortB = "127.0.0.1:5080"; int first = 0, second = 0; private static void usage() { System.out.println(usageString); System.exit(0); } public void processRequest(RequestEvent requestReceivedEvent) { Request request = requestReceivedEvent.getRequest(); ServerTransaction serverTransactionId = requestReceivedEvent .getServerTransaction(); System.out.println("\n\nRequest " + request.getMethod() + " received at " + sipStack.getStackName() + " with server transaction id " + serverTransactionId); // We are the UAC so the only request we get is the BYE. if (request.getMethod().equals(Request.BYE)) processBye(request, serverTransactionId); } public void processBye(Request request, ServerTransaction serverTransactionId) { try { System.out.println("Controller: got a bye ."); if (serverTransactionId == null) { System.out.println("Controller: null TID."); return; } System.out.println("Create OK para BYE: "); // 1: OK BYE Response ok = messageFactory.createResponse(Response.OK, request); serverTransactionId.sendResponse(ok); // 2do: BYE for the other side (send a new clientTransaction) System.out.println("Send BYE in new clientTransaction"); Dialog secondBye = (Dialog) (serverTransactionId.getDialog() .getApplicationData()); Request requestBye = secondBye.createRequest(Request.BYE); ClientTransaction clientTransaction = null; clientTransaction = sipProvider.getNewClientTransaction(requestBye); secondBye.sendRequest(clientTransaction); } catch (Exception ex) { ex.printStackTrace(); System.exit(0); } } public void processResponse(ResponseEvent responseReceivedEvent) { System.out.println("Got a response"); Response response = (Response) responseReceivedEvent.getResponse(); ClientTransaction tid = responseReceivedEvent.getClientTransaction(); CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); System.out.println("Response received : Status Code = " + response.getStatusCode() + " " + cseq); if (tid == null) { System.out.println("Stray response -- dropping "); return; } System.out.println("transaction state is " + tid.getState()); System.out.println("Dialog = " + tid.getDialog()); System.out.println("Dialog State is " + tid.getDialog().getState()); try { if (response.getStatusCode() == Response.OK) { if (cseq.getMethod().equals(Request.INVITE)) { if (Secuencia.equals("first")) { System.out.println("processResponse FIRST"); responseFirstEvent = responseReceivedEvent; // get call-id String callId = ((CallIdHeader) response .getHeader(CallIdHeader.NAME)).getCallId(); // Create second Invite second++; Secuencia = "second"; Request requestSecond = this.createInvite(Secuencia, String.valueOf(second), callId, null, peerHostPortB); // SDP for second Invite with first response // ContentTypeHeader requestSecond.setContent(response.getContent(), (ContentTypeHeader) (response .getHeader("Content-Type"))); inviteSecond = sipProvider .getNewClientTransaction(requestSecond); inviteSecond.sendRequest(); System.out.println("INVITE second sent:\n" + requestSecond); } else if (Secuencia.equals("second")) { System.out.println("processResponse SECOND"); // send ACK second Dialog dialogSecond = tid.getDialog(); Request ackRequest = dialogSecond.createAck(cseq .getSeqNumber());// dialogSecond.createRequest(Request.ACK); System.out.println("Sending ACK second"); dialogSecond.sendAck(ackRequest);// dialogSecond.sendAck(ackRequest); CSeqHeader cseqFirst = (CSeqHeader) responseFirstEvent .getResponse().getHeader(CSeqHeader.NAME); Request ackRequestFirst = responseFirstEvent .getDialog().createAck( cseqFirst.getSeqNumber()); ackRequestFirst.setContent(response.getContent(), (ContentTypeHeader) (response .getHeader("Content-Type"))); System.out.println("Sending ACK first"); responseFirstEvent.getDialog().sendAck(ackRequestFirst); // save the dialog of the other side, for the bye... responseFirstEvent.getDialog().setApplicationData( dialogSecond); dialogSecond.setApplicationData(responseFirstEvent .getDialog()); Secuencia = "fin"; } } } } catch (Exception ex) { ex.printStackTrace(); System.exit(0); } } public Request createInvite(String headerName, String headerValue, String callerId, String tagVal, String peerHostPort) throws ParseException, InvalidArgumentException { String fromSipAddressDomain = "", toSipAddressDomain = ""; String fromDisplayName = ""; String toDisplayName = ""; String fromVal = "", toVal = ""; if (headerName.equals("first")) { fromVal = Auser; fromSipAddressDomain = ASipAddressDomain; fromDisplayName = ADisplayName; toVal = Buser; toSipAddressDomain = BSipAddressDomain; toDisplayName = BDisplayName; } else if (headerName.equals("second")) { fromVal = Buser; fromSipAddressDomain = BSipAddressDomain; fromDisplayName = BDisplayName; toVal = Auser; toSipAddressDomain = ASipAddressDomain; toDisplayName = ADisplayName; } System.out.println("CreateInvite "); // create >From Header SipURI fromAddress = addressFactory.createSipURI(fromVal, fromSipAddressDomain); Address fromNameAddress = addressFactory.createAddress(fromAddress); fromNameAddress.setDisplayName(fromDisplayName); FromHeader fromHeader = headerFactory.createFromHeader(fromNameAddress, "12345"); // create To Header SipURI toAddress = addressFactory.createSipURI(toVal, toSipAddressDomain); Address toNameAddress = addressFactory.createAddress(toAddress); toNameAddress.setDisplayName(toDisplayName); ToHeader toHeader = headerFactory.createToHeader(toNameAddress, null); // create Request URI SipURI requestURI = addressFactory.createSipURI(toVal, peerHostPort); // Create ViaHeaders ArrayList viaHeaders = new ArrayList(); ViaHeader viaHeader = headerFactory.createViaHeader("127.0.0.1", sipProvider.getListeningPoint(transport).getPort(), transport, null); viaHeaders.add(viaHeader); // Create a new CallId header CallIdHeader callIdHeader = null; if (callerId == null) { callIdHeader = sipProvider.getNewCallId(); } else { callIdHeader = headerFactory.createCallIdHeader(callerId); } // Create a new Cseq header CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(Long .parseLong(headerValue), Request.INVITE); // Create a new MaxForwardsHeader MaxForwardsHeader maxForwards = headerFactory .createMaxForwardsHeader(70); // Create the request. Request request = messageFactory.createRequest(requestURI, Request.INVITE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards); // Create contact headers String host = "127.0.0.1"; SipURI contactUrl = addressFactory.createSipURI(fromVal, host); contactUrl.setPort(udpListeningPoint.getPort()); // Create the contact name address. SipURI contactURI = addressFactory.createSipURI(fromVal, host); contactURI.setPort(sipProvider.getListeningPoint(transport).getPort()); Address contactAddress = addressFactory.createAddress(contactURI); // Add the contact address. contactAddress.setDisplayName(fromVal); contactHeader = headerFactory.createContactHeader(contactAddress); request.addHeader(contactHeader); // Allow header. With PUBLISH, to indicate that we'd like to have an // server-sided PA String methods = Request.INVITE + ", " + Request.ACK + ", " + Request.OPTIONS + ", " + Request.CANCEL + ", " + Request.BYE + ", " + Request.INFO + ", " + Request.REFER + ", " + Request.MESSAGE + ", " + Request.NOTIFY + ", " + Request.SUBSCRIBE; AllowHeader allowHeader = headerFactory.createAllowHeader(methods); request.addHeader(allowHeader); // Add the extension header. To mantain Flow I Header extensionHeader = headerFactory.createHeader(headerName, headerValue); request.addHeader(extensionHeader); return request; } public void init() { SipFactory sipFactory = null; sipStack = null; sipFactory = SipFactory.getInstance(); sipFactory.setPathName("gov.nist"); Properties properties = new Properties(); // This one is optional so I remove it, since I will call 2 parts // properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort + "/" // + transport); properties.setProperty("javax.sip.STACK_NAME", "controller"); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "controllerdebug.txt"); properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "controllerlog.txt"); properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "16"); try { sipStack = sipFactory.createSipStack(properties); System.out.println("createSipStack " + sipStack); headerFactory = sipFactory.createHeaderFactory(); addressFactory = sipFactory.createAddressFactory(); messageFactory = sipFactory.createMessageFactory(); udpListeningPoint = sipStack.createListeningPoint("127.0.0.1", 5050, "udp"); sipProvider = sipStack.createSipProvider(udpListeningPoint); Controller listener = this; sipProvider.addSipListener(listener); } catch (PeerUnavailableException e) { e.printStackTrace(); System.err.println(e.getMessage()); System.exit(0); } catch (Exception e) { System.out.println("Creating Listener Points"); System.out.println(e.getMessage()); e.printStackTrace(); } try { System.out.println("ProcessCTD "); first++; this.Secuencia = "first"; Request request = this.createInvite(Secuencia, String .valueOf(first), "", null, peerHostPortA); // Create the client transaction. inviteFirst = sipProvider.getNewClientTransaction(request); // send the request out. inviteFirst.sendRequest(); System.out.println("INVITE first sent:\n" + request); } catch (Exception e) { System.out.println("Creating call CreateInvite()"); System.out.println(e.getMessage()); e.printStackTrace(); } } public static void main(String args[]) { new Controller().init(); } public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { System.out.println("Transaction Time out"); } public void processIOException(IOExceptionEvent exceptionEvent) { System.out.println("IOException happened for " + exceptionEvent.getHost() + " port = " + exceptionEvent.getPort()); } public void processTransactionTerminated( TransactionTerminatedEvent transactionTerminatedEvent) { System.out.println("Transaction terminated event recieved"); } public void processDialogTerminated( DialogTerminatedEvent dialogTerminatedEvent) { System.out.println("dialogTerminatedEvent"); } }