001: /*
002: * Conditions Of Use
003: *
004: * This software was developed by employees of the National Institute of
005: * Standards and Technology (NIST), and others.
006: * This software is has been contributed to the public domain.
007: * As a result, a formal license is not needed to use the software.
008: *
009: * This software is provided "AS IS."
010: * NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
011: * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
012: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
013: * AND DATA ACCURACY. NIST does not warrant or make any representations
014: * regarding the use of the software or the results thereof, including but
015: * not limited to the correctness, accuracy, reliability or usefulness of
016: * the software.
017: *
018: *
019: */
020: package test.tck.msgflow.callflows.tls;
021:
022: import javax.sip.*;
023: import javax.sip.address.*;
024: import javax.sip.header.*;
025: import javax.sip.message.*;
026:
027: import org.apache.log4j.ConsoleAppender;
028: import org.apache.log4j.Logger;
029: import org.apache.log4j.SimpleLayout;
030: import org.apache.log4j.helpers.NullEnumeration;
031:
032: import test.tck.msgflow.callflows.ProtocolObjects;
033:
034: /**
035: * This class is a UAC template.
036: *
037: * @author M. Ranganathan
038: */
039:
040: public class Shootme implements SipListener {
041:
042: private ProtocolObjects protocolObjects;
043:
044: // To run on two machines change these to suit.
045: public static final String myAddress = "127.0.0.1";
046:
047: public static final int myPort = 5070;
048:
049: private ServerTransaction inviteTid;
050:
051: private static Logger logger = Logger.getLogger(Shootme.class);
052:
053: static {
054: if (logger.getAllAppenders().equals(
055: NullEnumeration.getInstance())) {
056:
057: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
058:
059: }
060: }
061:
062: private Dialog dialog;
063:
064: private boolean okRecieved;
065:
066: class ApplicationData {
067: protected int ackCount;
068: }
069:
070: public Shootme(ProtocolObjects protocolObjects) {
071: this .protocolObjects = protocolObjects;
072: }
073:
074: public void processRequest(RequestEvent requestEvent) {
075: Request request = requestEvent.getRequest();
076: ServerTransaction serverTransactionId = requestEvent
077: .getServerTransaction();
078: logger.info("\n\nRequest " + request.getMethod()
079: + " received at "
080: + protocolObjects.sipStack.getStackName()
081: + " with server transaction id " + serverTransactionId);
082:
083: if (request.getMethod().equals(Request.INVITE)) {
084: processInvite(requestEvent, serverTransactionId);
085: } else if (request.getMethod().equals(Request.ACK)) {
086: processAck(requestEvent, serverTransactionId);
087: } else if (request.getMethod().equals(Request.BYE)) {
088: processBye(requestEvent, serverTransactionId);
089: }
090:
091: }
092:
093: /**
094: * Process the ACK request. Send the bye and complete the call flow.
095: */
096: public void processAck(RequestEvent requestEvent,
097: ServerTransaction serverTransaction) {
098: SipProvider sipProvider = (SipProvider) requestEvent
099: .getSource();
100: try {
101: logger.info("shootme: got an ACK "
102: + requestEvent.getRequest());
103:
104: int ackCount = ((ApplicationData) dialog
105: .getApplicationData()).ackCount;
106: if (ackCount == 1) {
107: dialog = inviteTid.getDialog();
108: this .sendReInvite(sipProvider);
109:
110: } else
111: ((ApplicationData) dialog.getApplicationData()).ackCount++;
112: } catch (Exception ex) {
113: String s = "Unexpected error";
114: logger.error(s, ex);
115: TlsTest.fail(s);
116: }
117: }
118:
119: /**
120: * Process the invite request.
121: */
122: public void processInvite(RequestEvent requestEvent,
123: ServerTransaction st) {
124: SipProvider sipProvider = (SipProvider) requestEvent
125: .getSource();
126: Request request = requestEvent.getRequest();
127: logger.info("Got an INVITE " + request);
128: try {
129: logger.info("shootme: got an Invite sending OK");
130: // logger.info("shootme: " + request);
131: Response response = protocolObjects.messageFactory
132: .createResponse(180, request);
133: ToHeader toHeader = (ToHeader) response
134: .getHeader(ToHeader.NAME);
135: toHeader.setTag("4321");
136: Address address = protocolObjects.addressFactory
137: .createAddress("Shootme <sips:" + myAddress + ":"
138: + myPort + ">");
139: ContactHeader contactHeader = protocolObjects.headerFactory
140: .createContactHeader(address);
141: response.addHeader(contactHeader);
142: if (st == null) {
143: st = sipProvider.getNewServerTransaction(request);
144: logger.info("Server transaction created!" + request);
145:
146: logger.info("Dialog = " + st.getDialog());
147: if (st.getDialog().getApplicationData() == null) {
148: st.getDialog().setApplicationData(
149: new ApplicationData());
150: }
151: } else {
152: // If Server transaction is not null, then
153: // this is a re-invite.
154: logger.info("This is a RE INVITE ");
155: TlsTest.assertSame("Dialog mismatch ", st.getDialog(),
156: this .dialog);
157: TlsTest.assertTrue("Secure dialog", this .dialog
158: .isSecure());
159: }
160:
161: // Thread.sleep(5000);
162: logger.info("got a server tranasaction " + st);
163: byte[] content = request.getRawContent();
164: if (content != null) {
165: logger.info(" content = " + new String(content));
166: ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
167: .createContentTypeHeader("application", "sdp");
168: logger.info("response = " + response);
169: response.setContent(content, contentTypeHeader);
170: }
171: dialog = st.getDialog();
172: if (dialog != null) {
173: logger.info("Dialog " + dialog);
174: logger.info("Dialog state " + dialog.getState());
175: }
176: st.sendResponse(response);
177: response = protocolObjects.messageFactory.createResponse(
178: 200, request);
179: toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
180: toHeader.setTag("4321");
181: // Application is supposed to set.
182: response.addHeader(contactHeader);
183: st.sendResponse(response);
184: logger
185: .info("TxState after sendResponse = "
186: + st.getState());
187: this .inviteTid = st;
188: } catch (Exception ex) {
189: String s = "unexpected exception";
190:
191: logger.error(s, ex);
192: TlsTest.fail(s);
193: }
194: }
195:
196: public void sendReInvite(SipProvider sipProvider) throws Exception {
197: Request inviteRequest = dialog.createRequest(Request.INVITE);
198: ClientTransaction ct = sipProvider
199: .getNewClientTransaction(inviteRequest);
200: dialog.sendRequest(ct);
201: }
202:
203: /**
204: * Process the bye request.
205: */
206: public void processBye(RequestEvent requestEvent,
207: ServerTransaction serverTransactionId) {
208:
209: SipProvider sipProvider = (SipProvider) requestEvent
210: .getSource();
211: Request request = requestEvent.getRequest();
212: try {
213: logger.info("shootme: got a bye sending OK.");
214: Response response = protocolObjects.messageFactory
215: .createResponse(200, request);
216: if (serverTransactionId != null) {
217: serverTransactionId.sendResponse(response);
218: logger.info("Dialog State is "
219: + serverTransactionId.getDialog().getState());
220: } else {
221: logger.info("null server tx.");
222: // sipProvider.sendResponse(response);
223: }
224:
225: } catch (Exception ex) {
226: String s = "Unexpected exception";
227: logger.error(s, ex);
228: TlsTest.fail(s);
229:
230: }
231: }
232:
233: public void processResponse(ResponseEvent responseReceivedEvent) {
234: logger.info("Got a response");
235: Response response = (Response) responseReceivedEvent
236: .getResponse();
237: Transaction tid = responseReceivedEvent.getClientTransaction();
238:
239: logger.info("Response received with client transaction id "
240: + tid + ":\n" + response);
241: try {
242: if (response.getStatusCode() == Response.OK
243: && ((CSeqHeader) response
244: .getHeader(CSeqHeader.NAME)).getMethod()
245: .equals(Request.INVITE)) {
246: this .okRecieved = true;
247: TlsTest
248: .assertNotNull(
249: "INVITE 200 response should match a transaction",
250: tid);
251: Dialog dialog = tid.getDialog();
252: CSeqHeader cseq = (CSeqHeader) response
253: .getHeader(CSeqHeader.NAME);
254: Request request = dialog.createAck(cseq.getSeqNumber());
255: dialog.sendAck(request);
256: }
257: if (tid != null) {
258: Dialog dialog = tid.getDialog();
259: logger.info("Dalog State = " + dialog.getState());
260: }
261: } catch (Exception ex) {
262:
263: String s = "Unexpected exception";
264:
265: logger.error(s, ex);
266: TlsTest.fail(s);
267: }
268:
269: }
270:
271: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
272: Transaction transaction;
273: if (timeoutEvent.isServerTransaction()) {
274: transaction = timeoutEvent.getServerTransaction();
275: } else {
276: transaction = timeoutEvent.getClientTransaction();
277: }
278: logger.info("state = " + transaction.getState());
279: logger.info("dialog = " + transaction.getDialog());
280: logger.info("dialogState = "
281: + transaction.getDialog().getState());
282: logger.info("Transaction Time out");
283: }
284:
285: public SipProvider createSipProvider() throws Exception {
286: ListeningPoint lp = protocolObjects.sipStack
287: .createListeningPoint(myAddress, myPort,
288: protocolObjects.transport);
289:
290: SipProvider sipProvider = protocolObjects.sipStack
291: .createSipProvider(lp);
292: return sipProvider;
293: }
294:
295: public static void main(String args[]) throws Exception {
296: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
297: ProtocolObjects protocolObjects = new ProtocolObjects(
298: "shootme", "gov.nist", "udp", true);
299:
300: Shootme shootme = new Shootme(protocolObjects);
301: shootme.createSipProvider().addSipListener(shootme);
302:
303: }
304:
305: public void checkState() {
306: ApplicationData data = (ApplicationData) dialog
307: .getApplicationData();
308: TlsTest.assertTrue(data.ackCount == 1);
309: TlsTest.assertTrue(okRecieved);
310: }
311:
312: /*
313: * (non-Javadoc)
314: *
315: * @see javax.sip.SipListener#processIOException(javax.sip.IOExceptionEvent)
316: */
317: public void processIOException(IOExceptionEvent exceptionEvent) {
318: logger.error("An IO Exception was detected : "
319: + exceptionEvent.getHost());
320:
321: }
322:
323: /*
324: * (non-Javadoc)
325: *
326: * @see javax.sip.SipListener#processTransactionTerminated(javax.sip.TransactionTerminatedEvent)
327: */
328: public void processTransactionTerminated(
329: TransactionTerminatedEvent transactionTerminatedEvent) {
330: logger.info("Tx terminated event ");
331:
332: }
333:
334: /*
335: * (non-Javadoc)
336: *
337: * @see javax.sip.SipListener#processDialogTerminated(javax.sip.DialogTerminatedEvent)
338: */
339: public void processDialogTerminated(
340: DialogTerminatedEvent dialogTerminatedEvent) {
341: logger.info("Dialog terminated event detected ");
342:
343: }
344:
345: }
|