001: package examples.cancel;
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.Logger;
010: import org.apache.log4j.SimpleLayout;
011:
012: import java.util.*;
013:
014: import junit.framework.TestCase;
015:
016: /**
017: * This class is a UAC template. Shootist is the guy that shoots and shootme is
018: * the guy that gets shot.
019: *
020: * @author M. Ranganathan
021: */
022:
023: public class Shootme extends TestCase implements SipListener {
024:
025: private static final String myAddress = "127.0.0.1";
026:
027: private static final String transport = "udp";
028:
029: private static final int myPort = 5070;
030:
031: private ServerTransaction inviteTid;
032:
033: private Response okResponse;
034:
035: private Request inviteRequest;
036:
037: private SipProvider sipProvider;
038:
039: private Dialog dialog;
040:
041: private static Logger logger = Logger.getLogger(Shootme.class);
042:
043: private static final String unexpectedException = "Unexpected Exception ";
044:
045: class MyTimerTask extends TimerTask {
046: Shootme shootme;
047:
048: public MyTimerTask(Shootme shootme) {
049: this .shootme = shootme;
050:
051: }
052:
053: public void run() {
054: shootme.sendInviteOK();
055: }
056:
057: }
058:
059: protected static final String usageString = "java "
060: + "examples.shootist.Shootist \n"
061: + ">>>> is your class path set to the root?";
062:
063: public void processRequest(RequestEvent requestEvent) {
064: Request request = requestEvent.getRequest();
065: ServerTransaction serverTransactionId = requestEvent
066: .getServerTransaction();
067:
068: logger.info("\n\nRequest " + request.getMethod()
069: + " received at "
070: + ProtocolObjects.sipStack.getStackName()
071: + " with server transaction id " + serverTransactionId);
072:
073: if (request.getMethod().equals(Request.INVITE)) {
074: processInvite(requestEvent, serverTransactionId);
075: } else if (request.getMethod().equals(Request.ACK)) {
076: processAck(requestEvent, serverTransactionId);
077: } else if (request.getMethod().equals(Request.BYE)) {
078: processBye(requestEvent, serverTransactionId);
079: } else if (request.getMethod().equals(Request.CANCEL)) {
080: processCancel(requestEvent, serverTransactionId);
081: }
082:
083: }
084:
085: public void processResponse(ResponseEvent responseEvent) {
086: }
087:
088: /**
089: * Process the ACK request. Send the bye and complete the call flow.
090: */
091: public void processAck(RequestEvent requestEvent,
092: ServerTransaction serverTransaction) {
093: SipProvider sipProvider = (SipProvider) requestEvent
094: .getSource();
095: try {
096: if (dialog.getState() == DialogState.CONFIRMED) {
097: Request byeRequest = dialog.createRequest(Request.BYE);
098: ClientTransaction tr = sipProvider
099: .getNewClientTransaction(byeRequest);
100: logger.info("shootme: got an ACK -- sending bye! ");
101: dialog.sendRequest(tr);
102: logger.info("Dialog State = " + dialog.getState());
103: }
104: } catch (Exception ex) {
105: logger.error(ex);
106: fail(unexpectedException);
107: }
108: }
109:
110: /**
111: * Process the invite request.
112: */
113: public void processInvite(RequestEvent requestEvent,
114: ServerTransaction serverTransaction) {
115: SipProvider sipProvider = (SipProvider) requestEvent
116: .getSource();
117: Request request = requestEvent.getRequest();
118: try {
119: logger.info("shootme: got an Invite sending RINGING");
120: // logger.info("shootme: " + request);
121: Response response = ProtocolObjects.messageFactory
122: .createResponse(180, request);
123: ToHeader toHeader = (ToHeader) response
124: .getHeader(ToHeader.NAME);
125: toHeader.setTag("4321"); // Application is supposed to set.
126: Address address = ProtocolObjects.addressFactory
127: .createAddress("Shootme <sip:" + myAddress + ":"
128: + myPort + ">");
129: ContactHeader contactHeader = ProtocolObjects.headerFactory
130: .createContactHeader(address);
131: response.addHeader(contactHeader);
132: ServerTransaction st = requestEvent.getServerTransaction();
133:
134: if (st == null) {
135: st = sipProvider.getNewServerTransaction(request);
136: logger.info("Created a new server transaction for "
137: + request.getMethod() + " serverTransaction = "
138: + st);
139: }
140: dialog = st.getDialog();
141:
142: st.sendResponse(response);
143: this .okResponse = ProtocolObjects.messageFactory
144: .createResponse(200, request);
145: toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME);
146: toHeader.setTag("4321"); // Application is supposed to set.
147: okResponse.addHeader(contactHeader);
148: this .inviteTid = st;
149: // Defer sending the OK to simulate the phone ringing.
150: this .inviteRequest = request;
151:
152: new Timer().schedule(new MyTimerTask(this ), 300);
153: } catch (Exception ex) {
154: logger.error(ex);
155: fail(unexpectedException);
156: }
157: }
158:
159: private void sendInviteOK() {
160: try {
161: if (inviteTid.getState() != TransactionState.COMPLETED) {
162: logger.info("shootme: got an Invite sending OK");
163: inviteTid.sendResponse(okResponse);
164: }
165: } catch (Exception ex) {
166: logger.error(ex);
167: }
168: }
169:
170: /**
171: * Process the bye request.
172: */
173: public void processBye(RequestEvent requestEvent,
174: ServerTransaction serverTransactionId) {
175:
176: Request request = requestEvent.getRequest();
177: try {
178: logger.info("shootme: got a bye sending OK.");
179: Response response = ProtocolObjects.messageFactory
180: .createResponse(200, request);
181: serverTransactionId.sendResponse(response);
182: logger.info("Dialog State is "
183: + serverTransactionId.getDialog().getState());
184:
185: } catch (Exception ex) {
186: logger.error(ex);
187: fail(unexpectedException);
188:
189: }
190: }
191:
192: public void processCancel(RequestEvent requestEvent,
193: ServerTransaction serverTransactionId) {
194:
195: Request request = requestEvent.getRequest();
196: try {
197: logger.info("shootme: got a cancel.");
198: if (serverTransactionId == null) {
199: logger.info("shootme: null tid.");
200: return;
201: }
202: TestCase.assertTrue(inviteTid != serverTransactionId);
203: Response response = ProtocolObjects.messageFactory
204: .createResponse(200, request);
205: serverTransactionId.sendResponse(response);
206: if (dialog.getState() != DialogState.CONFIRMED) {
207: response = ProtocolObjects.messageFactory
208: .createResponse(Response.REQUEST_TERMINATED,
209: inviteRequest);
210: inviteTid.sendResponse(response);
211: }
212:
213: } catch (Exception ex) {
214: logger.error(ex);
215: fail(unexpectedException);
216:
217: }
218: }
219:
220: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
221: Transaction transaction;
222: if (timeoutEvent.isServerTransaction()) {
223: transaction = timeoutEvent.getServerTransaction();
224: } else {
225: transaction = timeoutEvent.getClientTransaction();
226: }
227: logger.info("state = " + transaction.getState());
228: logger.info("dialog = " + transaction.getDialog());
229: logger.info("dialogState = "
230: + transaction.getDialog().getState());
231: logger.info("Transaction Time out");
232: }
233:
234: public SipProvider createProvider() {
235: try {
236:
237: ListeningPoint lp = ProtocolObjects.sipStack
238: .createListeningPoint(myAddress, myPort, transport);
239:
240: sipProvider = ProtocolObjects.sipStack
241: .createSipProvider(lp);
242: logger.info("udp provider " + sipProvider);
243: return sipProvider;
244: } catch (Exception ex) {
245: logger.error(ex);
246: fail(unexpectedException);
247: return null;
248:
249: }
250:
251: }
252:
253: public static void main(String args[]) throws Exception {
254: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
255: ProtocolObjects.init("shootme");
256: Shootme shootme = new Shootme();
257: shootme.createProvider();
258: shootme.sipProvider.addSipListener(shootme);
259: }
260:
261: public void processIOException(IOExceptionEvent exceptionEvent) {
262: // TODO Auto-generated method stub
263:
264: }
265:
266: public void processTransactionTerminated(
267: TransactionTerminatedEvent transactionTerminatedEvent) {
268: if (transactionTerminatedEvent.isServerTransaction()) {
269: ServerTransaction serverTx = transactionTerminatedEvent
270: .getServerTransaction();
271:
272: String method = serverTx.getRequest().getMethod();
273:
274: logger.info("Server Tx : " + method + " terminated ");
275: }
276: }
277:
278: public void processDialogTerminated(
279: DialogTerminatedEvent dialogTerminatedEvent) {
280: // TODO Auto-generated method stub
281:
282: }
283:
284: }
|