001: package test.tck.msgflow.callflows.recroute;
002:
003: import java.util.ArrayList;
004: import java.util.HashSet;
005: import java.util.Timer;
006: import java.util.TimerTask;
007:
008: import javax.sip.ClientTransaction;
009: import javax.sip.Dialog;
010: import javax.sip.DialogState;
011: import javax.sip.DialogTerminatedEvent;
012: import javax.sip.IOExceptionEvent;
013: import javax.sip.ListeningPoint;
014: import javax.sip.RequestEvent;
015: import javax.sip.ResponseEvent;
016: import javax.sip.ServerTransaction;
017: import javax.sip.SipListener;
018: import javax.sip.SipProvider;
019: import javax.sip.TransactionTerminatedEvent;
020: import javax.sip.address.Address;
021: import javax.sip.address.SipURI;
022: import javax.sip.header.CSeqHeader;
023: import javax.sip.header.CallIdHeader;
024: import javax.sip.header.ContactHeader;
025: import javax.sip.header.ContentTypeHeader;
026: import javax.sip.header.FromHeader;
027: import javax.sip.header.Header;
028: import javax.sip.header.MaxForwardsHeader;
029: import javax.sip.header.RouteHeader;
030: import javax.sip.header.ToHeader;
031: import javax.sip.header.ViaHeader;
032: import javax.sip.message.Request;
033: import javax.sip.message.Response;
034:
035: import org.apache.log4j.Logger;
036:
037: import test.tck.TestHarness;
038: import test.tck.msgflow.callflows.ProtocolObjects;
039:
040: /**
041: * This class is a UAC template. Shootist is the guy that shoots and shootme is
042: * the guy that gets shot.
043: *
044: * @author M. Ranganathan
045: * @author Jeroen van Bemmel
046: */
047:
048: public class Shootist implements SipListener {
049:
050: private ContactHeader contactHeader;
051:
052: private ClientTransaction inviteTid;
053:
054: private SipProvider sipProvider;
055:
056: private String host = "127.0.0.1";
057:
058: private int port;
059:
060: private String peerHost = "127.0.0.1";
061:
062: private int peerPort;
063:
064: private ListeningPoint listeningPoint;
065:
066: private static String unexpectedException = "Unexpected exception ";
067:
068: private static Logger logger = Logger.getLogger("test.tck");
069:
070: private ProtocolObjects protocolObjects;
071:
072: private boolean byeReceived;
073:
074: private boolean infoReceived;
075:
076: public Shootist(int myPort, int proxyPort,
077: ProtocolObjects protocolObjects) {
078: this .protocolObjects = protocolObjects;
079: this .port = myPort;
080: this .peerPort = proxyPort;
081:
082: protocolObjects.logLevel = 32; // JvB
083: }
084:
085: public void processRequest(RequestEvent requestReceivedEvent) {
086: Request request = requestReceivedEvent.getRequest();
087: ServerTransaction serverTransactionId = requestReceivedEvent
088: .getServerTransaction();
089:
090: logger.info("\n\nRequest " + request.getMethod()
091: + " received at "
092: + protocolObjects.sipStack.getStackName()
093: + " with server transaction id " + serverTransactionId);
094:
095: // We are the UAC so the only request we get is the BYE.
096: if (request.getMethod().equals(Request.INFO))
097: processInfo(requestReceivedEvent);
098: else
099: TestHarness.fail("Unexpected request ! : " + request);
100:
101: }
102:
103: public void processInfo(RequestEvent requestEvent) {
104: try {
105: this .infoReceived = true;
106: logger.info("This is the info request "
107: + requestEvent.getRequest());
108: logger.info("This is the dialog "
109: + requestEvent.getDialog());
110: SipProvider sipProvider = (SipProvider) requestEvent
111: .getSource();
112: Dialog dialog = requestEvent.getDialog();
113:
114: ServerTransaction serverTransaction = requestEvent
115: .getServerTransaction();
116: Response ok = protocolObjects.messageFactory
117: .createResponse(Response.OK, requestEvent
118: .getRequest());
119: serverTransaction.sendResponse(ok);
120:
121: new Timer().schedule(new TimerTask() {
122: Dialog dialog;
123: SipProvider sipProvider;
124:
125: public TimerTask setInfo(SipProvider provider,
126: Dialog dialog) {
127: this .dialog = dialog;
128: this .sipProvider = provider;
129: return this ;
130: }
131:
132: @Override
133: public void run() {
134: try {
135: Request byeRequest = dialog
136: .createRequest(Request.BYE);
137: ClientTransaction ct = sipProvider
138: .getNewClientTransaction(byeRequest);
139: dialog.sendRequest(ct);
140: } catch (Exception ex) {
141: TestHarness.fail(
142: "Unexpected exception sending BYE", ex);
143: }
144:
145: }
146:
147: }.setInfo(sipProvider, dialog), 1000);
148:
149: } catch (Exception ex) {
150: ex.printStackTrace();
151: System.exit(0);
152:
153: }
154: }
155:
156: public synchronized void processResponse(
157: ResponseEvent responseReceivedEvent) {
158: logger.info("Got a response");
159: Response response = (Response) responseReceivedEvent
160: .getResponse();
161: ClientTransaction tid = responseReceivedEvent
162: .getClientTransaction();
163: CSeqHeader cseq = (CSeqHeader) response
164: .getHeader(CSeqHeader.NAME);
165:
166: logger.info("Response received : Status Code = "
167: + response.getStatusCode() + " " + cseq);
168: logger.info("Response = " + response + " class="
169: + response.getClass());
170:
171: Dialog dialog = responseReceivedEvent.getDialog();
172: TestHarness.assertNotNull(dialog);
173:
174: if (tid != null)
175: logger.info("transaction state is " + tid.getState());
176: else
177: logger.info("transaction = " + tid);
178:
179: logger.info("Dialog = " + dialog);
180:
181: logger.info("Dialog state is " + dialog.getState());
182:
183: try {
184: if (response.getStatusCode() == Response.OK) {
185: if (cseq.getMethod().equals(Request.INVITE)) {
186: TestHarness.assertEquals(DialogState.CONFIRMED,
187: dialog.getState());
188: Request ackRequest = dialog.createAck(cseq
189: .getSeqNumber());
190:
191: dialog.sendAck(ackRequest);
192:
193: TestHarness.assertNotNull(ackRequest
194: .getHeader(MaxForwardsHeader.NAME));
195:
196: // Proxy will fork. I will accept the second dialog
197: // but not the first.
198:
199: SipProvider sipProvider = (SipProvider) responseReceivedEvent
200: .getSource();
201:
202: Request infoRequest = dialog
203: .createRequest(Request.INFO);
204: ClientTransaction ct = sipProvider
205: .getNewClientTransaction(infoRequest);
206: dialog.sendRequest(ct);
207:
208: } else {
209: logger
210: .info("Response method = "
211: + cseq.getMethod());
212: }
213: } else if (response.getStatusCode() == Response.RINGING) {
214: // TestHarness.assertEquals( DialogState.EARLY,
215: // dialog.getState() );
216: }
217: } catch (Throwable ex) {
218: ex.printStackTrace();
219: // System.exit(0);
220: }
221:
222: }
223:
224: public SipProvider createSipProvider() {
225: try {
226: listeningPoint = protocolObjects.sipStack
227: .createListeningPoint(host, port,
228: protocolObjects.transport);
229:
230: logger
231: .info("listening point = " + host + " port = "
232: + port);
233: logger.info("listening point = " + listeningPoint);
234: sipProvider = protocolObjects.sipStack
235: .createSipProvider(listeningPoint);
236: return sipProvider;
237: } catch (Exception ex) {
238: logger.error(unexpectedException, ex);
239: TestHarness.fail(unexpectedException);
240: return null;
241: }
242:
243: }
244:
245: public void checkState() {
246: TestHarness.assertTrue("Should see an INFO", infoReceived);
247:
248: }
249:
250: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
251:
252: logger.info("Transaction Time out");
253: }
254:
255: public void sendInvite() {
256: try {
257:
258: String fromName = "BigGuy";
259: String fromSipAddress = "here.com";
260: String fromDisplayName = "The Master Blaster";
261:
262: String toSipAddress = "there.com";
263: String toUser = "LittleGuy";
264: String toDisplayName = "The Little Blister";
265:
266: // create >From Header
267: SipURI fromAddress = protocolObjects.addressFactory
268: .createSipURI(fromName, fromSipAddress);
269:
270: Address fromNameAddress = protocolObjects.addressFactory
271: .createAddress(fromAddress);
272: fromNameAddress.setDisplayName(fromDisplayName);
273: FromHeader fromHeader = protocolObjects.headerFactory
274: .createFromHeader(fromNameAddress, "12345");
275:
276: // create To Header
277: SipURI toAddress = protocolObjects.addressFactory
278: .createSipURI(toUser, toSipAddress);
279: Address toNameAddress = protocolObjects.addressFactory
280: .createAddress(toAddress);
281: toNameAddress.setDisplayName(toDisplayName);
282: ToHeader toHeader = protocolObjects.headerFactory
283: .createToHeader(toNameAddress, null);
284:
285: // create Request URI
286: String peerHostPort = peerHost + ":" + peerPort;
287: SipURI requestURI = protocolObjects.addressFactory
288: .createSipURI(toUser, peerHostPort);
289:
290: // Create ViaHeaders
291:
292: ArrayList viaHeaders = new ArrayList();
293: ViaHeader viaHeader = protocolObjects.headerFactory
294: .createViaHeader(host, sipProvider
295: .getListeningPoint(
296: protocolObjects.transport)
297: .getPort(), protocolObjects.transport, null);
298:
299: // add via headers
300: viaHeaders.add(viaHeader);
301:
302: SipURI sipuri = protocolObjects.addressFactory
303: .createSipURI(null, host);
304: sipuri.setPort(peerPort);
305: sipuri.setLrParam();
306:
307: RouteHeader routeHeader = protocolObjects.headerFactory
308: .createRouteHeader(protocolObjects.addressFactory
309: .createAddress(sipuri));
310:
311: // Create ContentTypeHeader
312: ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
313: .createContentTypeHeader("application", "sdp");
314:
315: // Create a new CallId header
316: CallIdHeader callIdHeader = sipProvider.getNewCallId();
317: // JvB: Make sure that the implementation matches the messagefactory
318: callIdHeader = protocolObjects.headerFactory
319: .createCallIdHeader(callIdHeader.getCallId());
320:
321: // Create a new Cseq header
322: CSeqHeader cSeqHeader = protocolObjects.headerFactory
323: .createCSeqHeader(1L, Request.INVITE);
324:
325: // Create a new MaxForwardsHeader
326: MaxForwardsHeader maxForwards = protocolObjects.headerFactory
327: .createMaxForwardsHeader(70);
328:
329: // Create the request.
330: Request request = protocolObjects.messageFactory
331: .createRequest(requestURI, Request.INVITE,
332: callIdHeader, cSeqHeader, fromHeader,
333: toHeader, viaHeaders, maxForwards);
334: // Create contact headers
335:
336: SipURI contactUrl = protocolObjects.addressFactory
337: .createSipURI(fromName, host);
338: contactUrl.setPort(listeningPoint.getPort());
339:
340: // Create the contact name address.
341: SipURI contactURI = protocolObjects.addressFactory
342: .createSipURI(fromName, host);
343: contactURI.setPort(sipProvider.getListeningPoint(
344: protocolObjects.transport).getPort());
345: contactURI.setTransportParam(protocolObjects.transport);
346:
347: Address contactAddress = protocolObjects.addressFactory
348: .createAddress(contactURI);
349:
350: // Add the contact address.
351: contactAddress.setDisplayName(fromName);
352:
353: contactHeader = protocolObjects.headerFactory
354: .createContactHeader(contactAddress);
355: request.addHeader(contactHeader);
356:
357: // Dont use the Outbound Proxy. Use Lr instead.
358: request.setHeader(routeHeader);
359:
360: // Add the extension header.
361: Header extensionHeader = protocolObjects.headerFactory
362: .createHeader("My-Header", "my header value");
363: request.addHeader(extensionHeader);
364:
365: String sdpData = "v=0\r\n"
366: + "o=4855 13760799956958020 13760799956958020"
367: + " IN IP4 129.6.55.78\r\n"
368: + "s=mysession session\r\n"
369: + "p=+46 8 52018010\r\n"
370: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
371: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
372: + "a=rtpmap:0 PCMU/8000\r\n"
373: + "a=rtpmap:4 G723/8000\r\n"
374: + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
375: byte[] contents = sdpData.getBytes();
376:
377: request.setContent(contents, contentTypeHeader);
378:
379: extensionHeader = protocolObjects.headerFactory
380: .createHeader("My-Other-Header",
381: "my new header value ");
382: request.addHeader(extensionHeader);
383:
384: Header callInfoHeader = protocolObjects.headerFactory
385: .createHeader("Call-Info",
386: "<http://www.antd.nist.gov>");
387: request.addHeader(callInfoHeader);
388:
389: // Create the client transaction.
390: inviteTid = sipProvider.getNewClientTransaction(request);
391: Dialog dialog = inviteTid.getDialog();
392:
393: TestHarness.assertTrue(
394: "Initial dialog state should be null", dialog
395: .getState() == null);
396:
397: // send the request out.
398: inviteTid.sendRequest();
399:
400: } catch (Exception ex) {
401: logger.error(unexpectedException, ex);
402: TestHarness.fail(unexpectedException);
403:
404: }
405: }
406:
407: public void processIOException(IOExceptionEvent exceptionEvent) {
408: logger.info("IOException happened for "
409: + exceptionEvent.getHost() + " port = "
410: + exceptionEvent.getPort());
411:
412: }
413:
414: public void processTransactionTerminated(
415: TransactionTerminatedEvent transactionTerminatedEvent) {
416: logger.info("Transaction terminated event recieved");
417: }
418:
419: public void processDialogTerminated(
420: DialogTerminatedEvent dialogTerminatedEvent) {
421: logger.info("dialogTerminatedEvent");
422:
423: }
424: }
|