001: package examples.forked.invite;
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 extends TestCase implements SipListener {
025:
026: private static String transport = "udp";
027:
028: private static final String myAddress = "127.0.0.1";
029:
030: private Hashtable serverTxTable = new Hashtable();
031:
032: private SipProvider sipProvider;
033:
034: private int myPort;
035:
036: private static String unexpectedException = "Unexpected exception ";
037:
038: private static Logger logger = Logger.getLogger(Shootme.class);
039:
040: static {
041: try {
042: logger.addAppender(new FileAppender(new SimpleLayout(),
043: ProtocolObjects.logFileDirectory
044: + "shootmeconsolelog.txt"));
045: } catch (Exception ex) {
046: throw new RuntimeException("could not open log file");
047: }
048: }
049:
050: class MyTimerTask extends TimerTask {
051: RequestEvent requestEvent;
052: String toTag;
053: ServerTransaction serverTx;
054:
055: public MyTimerTask(RequestEvent requestEvent,
056: ServerTransaction tx, String toTag) {
057: logger.info("MyTimerTask ");
058: this .requestEvent = requestEvent;
059: this .toTag = toTag;
060: this .serverTx = tx;
061:
062: }
063:
064: public void run() {
065: sendInviteOK(requestEvent, serverTx, toTag);
066: }
067:
068: }
069:
070: protected static final String usageString = "java "
071: + "examples.shootist.Shootist \n"
072: + ">>>> is your class path set to the root?";
073:
074: public void processRequest(RequestEvent requestEvent) {
075: Request request = requestEvent.getRequest();
076: ServerTransaction serverTransactionId = requestEvent
077: .getServerTransaction();
078:
079: logger.info("\n\nRequest " + request.getMethod()
080: + " received at shootme "
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: } else if (request.getMethod().equals(Request.CANCEL)) {
090: processCancel(requestEvent, serverTransactionId);
091: }
092:
093: }
094:
095: public void processResponse(ResponseEvent responseEvent) {
096: }
097:
098: /**
099: * Process the ACK request. Send the bye and complete the call flow.
100: */
101: public void processAck(RequestEvent requestEvent,
102: ServerTransaction serverTransaction) {
103: logger.info("shootme: got an ACK! ");
104: logger.info("Dialog = " + requestEvent.getDialog());
105: logger.info("Dialog State = "
106: + requestEvent.getDialog().getState());
107: }
108:
109: /**
110: * Process the invite request.
111: */
112: public void processInvite(RequestEvent requestEvent,
113: ServerTransaction serverTransaction) {
114: SipProvider sipProvider = (SipProvider) requestEvent
115: .getSource();
116: Request request = requestEvent.getRequest();
117: try {
118: logger.info("shootme: got an Invite sending Trying");
119: // logger.info("shootme: " + request);
120:
121: ServerTransaction st = requestEvent.getServerTransaction();
122:
123: if (st == null) {
124: logger.info("null server tx -- getting a new one");
125: st = sipProvider.getNewServerTransaction(request);
126: }
127:
128: logger.info("getNewServerTransaction : " + st);
129:
130: String txId = ((ViaHeader) request
131: .getHeader(ViaHeader.NAME)).getBranch();
132: this .serverTxTable.put(txId, st);
133:
134: // Create the 100 Trying response.
135: Response response = ProtocolObjects.messageFactory
136: .createResponse(Response.TRYING, request);
137: ListeningPoint lp = sipProvider.getListeningPoint("udp");
138: int myPort = lp.getPort();
139:
140: Address address = ProtocolObjects.addressFactory
141: .createAddress("Shootme <sip:" + myAddress + ":"
142: + myPort + ">");
143:
144: st.sendResponse(response);
145:
146: Response ringingResponse = ProtocolObjects.messageFactory
147: .createResponse(Response.RINGING, request);
148: ContactHeader contactHeader = ProtocolObjects.headerFactory
149: .createContactHeader(address);
150: response.addHeader(contactHeader);
151: ToHeader toHeader = (ToHeader) ringingResponse
152: .getHeader(ToHeader.NAME);
153: String toTag = new Integer((int) (Math.random() * 10000))
154: .toString();
155: toHeader.setTag(toTag); // Application is supposed to set.
156: ringingResponse.addHeader(contactHeader);
157: st.sendResponse(ringingResponse);
158: Dialog dialog = st.getDialog();
159: dialog.setApplicationData(st);
160:
161: new Timer().schedule(new MyTimerTask(requestEvent, st,
162: toTag), 100);
163: } catch (Exception ex) {
164: ex.printStackTrace();
165: System.exit(0);
166: }
167: }
168:
169: private void sendInviteOK(RequestEvent requestEvent,
170: ServerTransaction inviteTid, String toTag) {
171: try {
172: logger.info("sendInviteOK: " + inviteTid);
173: if (inviteTid.getState() != TransactionState.COMPLETED) {
174: logger.info("shootme: Dialog state before OK: "
175: + inviteTid.getDialog().getState());
176:
177: SipProvider sipProvider = (SipProvider) requestEvent
178: .getSource();
179: Request request = requestEvent.getRequest();
180: Response okResponse = ProtocolObjects.messageFactory
181: .createResponse(Response.OK, request);
182: ListeningPoint lp = sipProvider
183: .getListeningPoint("udp");
184: int myPort = lp.getPort();
185:
186: Address address = ProtocolObjects.addressFactory
187: .createAddress("Shootme <sip:" + myAddress
188: + ":" + myPort + ">");
189: ContactHeader contactHeader = ProtocolObjects.headerFactory
190: .createContactHeader(address);
191: okResponse.addHeader(contactHeader);
192: inviteTid.sendResponse(okResponse);
193: logger.info("shootme: Dialog state after OK: "
194: + inviteTid.getDialog().getState());
195: } else {
196: logger.info("semdInviteOK: inviteTid = " + inviteTid
197: + " state = " + inviteTid.getState());
198: }
199: } catch (Exception ex) {
200: ex.printStackTrace();
201: }
202: }
203:
204: /**
205: * Process the bye request.
206: */
207: public void processBye(RequestEvent requestEvent,
208: ServerTransaction serverTransactionId) {
209: Request request = requestEvent.getRequest();
210: try {
211: logger.info("shootme: got a bye sending OK.");
212: logger.info("shootme: dialog = "
213: + requestEvent.getDialog());
214: logger.info("shootme: dialogState = "
215: + requestEvent.getDialog().getState());
216: Response response = ProtocolObjects.messageFactory
217: .createResponse(200, request);
218: if (serverTransactionId != null) {
219: serverTransactionId.sendResponse(response);
220: }
221: logger.info("shootme: dialogState = "
222: + requestEvent.getDialog().getState());
223:
224: } catch (Exception ex) {
225: ex.printStackTrace();
226: System.exit(0);
227:
228: }
229: }
230:
231: public void processCancel(RequestEvent requestEvent,
232: ServerTransaction serverTransactionId) {
233: Request request = requestEvent.getRequest();
234: SipProvider sipProvider = (SipProvider) requestEvent
235: .getSource();
236: try {
237: logger.info("shootme: got a cancel. ");
238: // Because this is not an In-dialog request, you will get a null server Tx id here.
239: if (serverTransactionId == null) {
240: serverTransactionId = sipProvider
241: .getNewServerTransaction(request);
242: }
243: Response response = ProtocolObjects.messageFactory
244: .createResponse(200, request);
245: serverTransactionId.sendResponse(response);
246:
247: String serverTxId = ((ViaHeader) response
248: .getHeader(ViaHeader.NAME)).getBranch();
249: ServerTransaction serverTx = (ServerTransaction) this .serverTxTable
250: .get(serverTxId);
251: if (serverTx != null
252: && (serverTx.getState().equals(
253: TransactionState.TRYING) || serverTx
254: .getState().equals(
255: TransactionState.PROCEEDING))) {
256: Request originalRequest = serverTx.getRequest();
257: Response resp = ProtocolObjects.messageFactory
258: .createResponse(Response.REQUEST_TERMINATED,
259: originalRequest);
260: serverTx.sendResponse(resp);
261: }
262:
263: } catch (Exception ex) {
264: ex.printStackTrace();
265: System.exit(0);
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 createProvider() {
285: try {
286:
287: ListeningPoint lp = ProtocolObjects.sipStack
288: .createListeningPoint(myAddress, myPort, transport);
289:
290: sipProvider = ProtocolObjects.sipStack
291: .createSipProvider(lp);
292: logger.info("udp provider " + sipProvider);
293: return sipProvider;
294: } catch (Exception ex) {
295: logger.error(ex);
296: fail(unexpectedException);
297: return null;
298:
299: }
300:
301: }
302:
303: public Shootme(int myPort) {
304: this .myPort = myPort;
305: }
306:
307: public static void main(String args[]) throws Exception {
308: int myPort = new Integer(args[0]).intValue();
309:
310: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
311: ProtocolObjects.init("shootme_" + myPort, true);
312: Shootme shootme = new Shootme(myPort);
313: shootme.createProvider();
314: shootme.sipProvider.addSipListener(shootme);
315: }
316:
317: public void processIOException(IOExceptionEvent exceptionEvent) {
318: logger.info("IOException");
319:
320: }
321:
322: public void processTransactionTerminated(
323: TransactionTerminatedEvent transactionTerminatedEvent) {
324: logger.info("Transaction terminated event recieved");
325:
326: }
327:
328: public void processDialogTerminated(
329: DialogTerminatedEvent dialogTerminatedEvent) {
330: logger.info("Dialog terminated event recieved");
331:
332: }
333:
334: }
|