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