001: package examples.tpcc;
002:
003: import javax.sip.*;
004: import javax.sip.address.*;
005: import javax.sip.header.*;
006: import javax.sip.message.*;
007: import java.util.*;
008: import java.text.ParseException;
009:
010: /**
011: * The Click to dial third party call controller application.
012: *
013: * @author Kathleen McCallum
014: *
015: * <pre>
016: * main () -> init()
017: * init()
018: * createSipStack
019: * createInvite() -> First
020: * processResponse()
021: * if (OK) first
022: * createInvite() -> second
023: * else if (OK) second
024: * ack() -> second
025: * ack() -> first
026: * </pre>
027: *
028: *
029: *
030: */
031:
032: public class Controller implements SipListener {
033:
034: private static SipProvider sipProvider;
035:
036: private static AddressFactory addressFactory;
037:
038: private static MessageFactory messageFactory;
039:
040: private static HeaderFactory headerFactory;
041:
042: private static SipStack sipStack;
043:
044: private ContactHeader contactHeader;
045:
046: private ListeningPoint udpListeningPoint;
047:
048: protected ClientTransaction inviteFirst;
049:
050: protected ClientTransaction inviteSecond;
051:
052: String Secuencia;
053:
054: String transport = "udp";
055:
056: protected static final String usageString = "java "
057: + "examples.ctd.ctdControll \n"
058: + ">>>> is your class path set to the root?";
059:
060: ResponseEvent responseFirstEvent;
061:
062: String Auser = "AGuy";
063:
064: String ASipAddressDomain = "Afirst.com";
065:
066: String ADisplayName = "The A first";
067:
068: String Buser = "BGuy";
069:
070: String BSipAddressDomain = "BSecond.com";
071:
072: String BDisplayName = "The B second";
073:
074: String peerHostPortA = "127.0.0.1:5070";
075:
076: String peerHostPortB = "127.0.0.1:5080";
077:
078: int first = 0, second = 0;
079:
080: private static void usage() {
081: System.out.println(usageString);
082: System.exit(0);
083: }
084:
085: public void processRequest(RequestEvent requestReceivedEvent) {
086: Request request = requestReceivedEvent.getRequest();
087: ServerTransaction serverTransactionId = requestReceivedEvent
088: .getServerTransaction();
089:
090: System.out.println("\n\nRequest " + request.getMethod()
091: + " received at " + sipStack.getStackName()
092: + " with server transaction id " + serverTransactionId);
093:
094: // We are the UAC so the only request we get is the BYE.
095: if (request.getMethod().equals(Request.BYE))
096: processBye(request, serverTransactionId);
097:
098: }
099:
100: public void processBye(Request request,
101: ServerTransaction serverTransactionId) {
102:
103: try {
104: System.out.println("Controller: got a bye .");
105: if (serverTransactionId == null) {
106: System.out.println("Controller: null TID.");
107: return;
108: }
109:
110: System.out.println("Create OK para BYE: ");
111: // 1: OK BYE
112: Response ok = messageFactory.createResponse(Response.OK,
113: request);
114: serverTransactionId.sendResponse(ok);
115:
116: // 2do: BYE for the other side (send a new clientTransaction)
117: System.out.println("Send BYE in new clientTransaction");
118:
119: Dialog secondBye = (Dialog) (serverTransactionId
120: .getDialog().getApplicationData());
121: Request requestBye = secondBye.createRequest(Request.BYE);
122: ClientTransaction clientTransaction = null;
123: clientTransaction = sipProvider
124: .getNewClientTransaction(requestBye);
125: secondBye.sendRequest(clientTransaction);
126:
127: } catch (Exception ex) {
128: ex.printStackTrace();
129: System.exit(0);
130:
131: }
132: }
133:
134: public void processResponse(ResponseEvent responseReceivedEvent) {
135: System.out.println("Got a response");
136: Response response = (Response) responseReceivedEvent
137: .getResponse();
138: ClientTransaction tid = responseReceivedEvent
139: .getClientTransaction();
140: CSeqHeader cseq = (CSeqHeader) response
141: .getHeader(CSeqHeader.NAME);
142:
143: System.out.println("Response received : Status Code = "
144: + response.getStatusCode() + " " + cseq);
145: if (tid == null) {
146: System.out.println("Stray response -- dropping ");
147: return;
148: }
149: System.out.println("transaction state is " + tid.getState());
150: System.out.println("Dialog = " + tid.getDialog());
151: System.out.println("Dialog State is "
152: + tid.getDialog().getState());
153:
154: try {
155: if (response.getStatusCode() == Response.OK) {
156: if (cseq.getMethod().equals(Request.INVITE)) {
157: if (Secuencia.equals("first")) {
158: System.out.println("processResponse FIRST");
159:
160: responseFirstEvent = responseReceivedEvent;
161: // get call-id
162: String callId = ((CallIdHeader) response
163: .getHeader(CallIdHeader.NAME))
164: .getCallId();
165: // Create second Invite
166: second++;
167: Secuencia = "second";
168: Request requestSecond = this .createInvite(
169: Secuencia, String.valueOf(second),
170: callId, null, peerHostPortB);
171: // SDP for second Invite with first response
172: // ContentTypeHeader
173: requestSecond.setContent(response.getContent(),
174: (ContentTypeHeader) (response
175: .getHeader("Content-Type")));
176:
177: inviteSecond = sipProvider
178: .getNewClientTransaction(requestSecond);
179:
180: inviteSecond.sendRequest();
181: System.out.println("INVITE second sent:\n"
182: + requestSecond);
183:
184: } else if (Secuencia.equals("second")) {
185: System.out.println("processResponse SECOND");
186: // send ACK second
187: Dialog dialogSecond = tid.getDialog();
188:
189: Request ackRequest = dialogSecond
190: .createAck(cseq.getSeqNumber());// dialogSecond.createRequest(Request.ACK);
191: System.out.println("Sending ACK second");
192: dialogSecond.sendAck(ackRequest);// dialogSecond.sendAck(ackRequest);
193:
194: CSeqHeader cseqFirst = (CSeqHeader) responseFirstEvent
195: .getResponse().getHeader(
196: CSeqHeader.NAME);
197: Request ackRequestFirst = responseFirstEvent
198: .getDialog().createAck(
199: cseqFirst.getSeqNumber());
200: ackRequestFirst.setContent(response
201: .getContent(),
202: (ContentTypeHeader) (response
203: .getHeader("Content-Type")));
204:
205: System.out.println("Sending ACK first");
206: responseFirstEvent.getDialog().sendAck(
207: ackRequestFirst);
208:
209: // save the dialog of the other side, for the bye...
210: responseFirstEvent.getDialog()
211: .setApplicationData(dialogSecond);
212: dialogSecond
213: .setApplicationData(responseFirstEvent
214: .getDialog());
215:
216: Secuencia = "fin";
217: }
218: }
219: }
220: } catch (Exception ex) {
221: ex.printStackTrace();
222: System.exit(0);
223: }
224: }
225:
226: public Request createInvite(String headerName, String headerValue,
227: String callerId, String tagVal, String peerHostPort)
228: throws ParseException, InvalidArgumentException {
229:
230: String fromSipAddressDomain = "", toSipAddressDomain = "";
231: String fromDisplayName = "";
232: String toDisplayName = "";
233: String fromVal = "", toVal = "";
234:
235: if (headerName.equals("first")) {
236: fromVal = Auser;
237: fromSipAddressDomain = ASipAddressDomain;
238: fromDisplayName = ADisplayName;
239: toVal = Buser;
240: toSipAddressDomain = BSipAddressDomain;
241: toDisplayName = BDisplayName;
242: } else if (headerName.equals("second")) {
243: fromVal = Buser;
244: fromSipAddressDomain = BSipAddressDomain;
245: fromDisplayName = BDisplayName;
246: toVal = Auser;
247: toSipAddressDomain = ASipAddressDomain;
248: toDisplayName = ADisplayName;
249: }
250: System.out.println("CreateInvite ");
251:
252: // create >From Header
253: SipURI fromAddress = addressFactory.createSipURI(fromVal,
254: fromSipAddressDomain);
255: Address fromNameAddress = addressFactory
256: .createAddress(fromAddress);
257: fromNameAddress.setDisplayName(fromDisplayName);
258: FromHeader fromHeader = headerFactory.createFromHeader(
259: fromNameAddress, "12345");
260:
261: // create To Header
262: SipURI toAddress = addressFactory.createSipURI(toVal,
263: toSipAddressDomain);
264: Address toNameAddress = addressFactory.createAddress(toAddress);
265: toNameAddress.setDisplayName(toDisplayName);
266: ToHeader toHeader = headerFactory.createToHeader(toNameAddress,
267: null);
268:
269: // create Request URI
270: SipURI requestURI = addressFactory.createSipURI(toVal,
271: peerHostPort);
272:
273: // Create ViaHeaders
274: ArrayList viaHeaders = new ArrayList();
275: ViaHeader viaHeader = headerFactory.createViaHeader(
276: "127.0.0.1", sipProvider.getListeningPoint(transport)
277: .getPort(), transport, null);
278: viaHeaders.add(viaHeader);
279:
280: // Create a new CallId header
281: CallIdHeader callIdHeader = null;
282: if (callerId == null) {
283: callIdHeader = sipProvider.getNewCallId();
284: } else {
285: callIdHeader = headerFactory.createCallIdHeader(callerId);
286: }
287:
288: // Create a new Cseq header
289: CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(Long
290: .parseLong(headerValue), Request.INVITE);
291:
292: // Create a new MaxForwardsHeader
293: MaxForwardsHeader maxForwards = headerFactory
294: .createMaxForwardsHeader(70);
295:
296: // Create the request.
297: Request request = messageFactory.createRequest(requestURI,
298: Request.INVITE, callIdHeader, cSeqHeader, fromHeader,
299: toHeader, viaHeaders, maxForwards);
300: // Create contact headers
301: String host = "127.0.0.1";
302: SipURI contactUrl = addressFactory.createSipURI(fromVal, host);
303: contactUrl.setPort(udpListeningPoint.getPort());
304:
305: // Create the contact name address.
306: SipURI contactURI = addressFactory.createSipURI(fromVal, host);
307: contactURI.setPort(sipProvider.getListeningPoint(transport)
308: .getPort());
309: Address contactAddress = addressFactory
310: .createAddress(contactURI);
311:
312: // Add the contact address.
313: contactAddress.setDisplayName(fromVal);
314: contactHeader = headerFactory
315: .createContactHeader(contactAddress);
316: request.addHeader(contactHeader);
317:
318: // Allow header. With PUBLISH, to indicate that we'd like to have an
319: // server-sided PA
320: String methods = Request.INVITE + ", " + Request.ACK + ", "
321: + Request.OPTIONS + ", " + Request.CANCEL + ", "
322: + Request.BYE + ", " + Request.INFO + ", "
323: + Request.REFER + ", " + Request.MESSAGE + ", "
324: + Request.NOTIFY + ", " + Request.SUBSCRIBE;
325: AllowHeader allowHeader = headerFactory
326: .createAllowHeader(methods);
327: request.addHeader(allowHeader);
328:
329: // Add the extension header. To mantain Flow I
330: Header extensionHeader = headerFactory.createHeader(headerName,
331: headerValue);
332: request.addHeader(extensionHeader);
333:
334: return request;
335: }
336:
337: public void init() {
338: SipFactory sipFactory = null;
339: sipStack = null;
340: sipFactory = SipFactory.getInstance();
341: sipFactory.setPathName("gov.nist");
342: Properties properties = new Properties();
343: // This one is optional so I remove it, since I will call 2 parts
344: // properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort + "/"
345: // + transport);
346: properties.setProperty("javax.sip.STACK_NAME", "controller");
347:
348: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
349: "controllerdebug.txt");
350: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
351: "controllerlog.txt");
352: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "16");
353:
354: try {
355: sipStack = sipFactory.createSipStack(properties);
356: System.out.println("createSipStack " + sipStack);
357:
358: headerFactory = sipFactory.createHeaderFactory();
359: addressFactory = sipFactory.createAddressFactory();
360: messageFactory = sipFactory.createMessageFactory();
361: udpListeningPoint = sipStack.createListeningPoint(
362: "127.0.0.1", 5050, "udp");
363: sipProvider = sipStack.createSipProvider(udpListeningPoint);
364: Controller listener = this ;
365: sipProvider.addSipListener(listener);
366:
367: } catch (PeerUnavailableException e) {
368: e.printStackTrace();
369: System.err.println(e.getMessage());
370: System.exit(0);
371: } catch (Exception e) {
372: System.out.println("Creating Listener Points");
373: System.out.println(e.getMessage());
374: e.printStackTrace();
375: }
376: try {
377: System.out.println("ProcessCTD ");
378: first++;
379: this .Secuencia = "first";
380: Request request = this .createInvite(Secuencia, String
381: .valueOf(first), "", null, peerHostPortA);
382: // Create the client transaction.
383: inviteFirst = sipProvider.getNewClientTransaction(request);
384: // send the request out.
385: inviteFirst.sendRequest();
386: System.out.println("INVITE first sent:\n" + request);
387:
388: } catch (Exception e) {
389: System.out.println("Creating call CreateInvite()");
390: System.out.println(e.getMessage());
391: e.printStackTrace();
392: }
393: }
394:
395: public static void main(String args[]) {
396: new Controller().init();
397: }
398:
399: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
400: System.out.println("Transaction Time out");
401: }
402:
403: public void processIOException(IOExceptionEvent exceptionEvent) {
404: System.out.println("IOException happened for "
405: + exceptionEvent.getHost() + " port = "
406: + exceptionEvent.getPort());
407: }
408:
409: public void processTransactionTerminated(
410: TransactionTerminatedEvent transactionTerminatedEvent) {
411: System.out.println("Transaction terminated event recieved");
412: }
413:
414: public void processDialogTerminated(
415: DialogTerminatedEvent dialogTerminatedEvent) {
416: System.out.println("dialogTerminatedEvent");
417: }
418: }
|