001: package examples.simplecallsetup;
002:
003: import javax.sip.*;
004: import javax.sip.address.*;
005: import javax.sip.header.*;
006: import javax.sip.message.*;
007:
008: import java.text.ParseException;
009: import java.util.*;
010:
011: /**
012: * This class is a UAC template.
013: *
014: * @author M. Ranganathan
015: */
016:
017: public class Shootist implements SipListener {
018:
019: private static SipProvider sipProvider;
020:
021: private static AddressFactory addressFactory;
022:
023: private static MessageFactory messageFactory;
024:
025: private static HeaderFactory headerFactory;
026:
027: private static SipStack sipStack;
028:
029: private ContactHeader contactHeader;
030:
031: private ListeningPoint udpListeningPoint;
032:
033: private ClientTransaction inviteTid;
034:
035: private Dialog dialog;
036:
037: private boolean byeTaskRunning;
038:
039: class ByeTask extends TimerTask {
040: Dialog dialog;
041:
042: public ByeTask(Dialog dialog) {
043: this .dialog = dialog;
044: }
045:
046: public void run() {
047: try {
048: Request byeRequest = this .dialog
049: .createRequest(Request.BYE);
050: ClientTransaction ct = sipProvider
051: .getNewClientTransaction(byeRequest);
052: dialog.sendRequest(ct);
053: } catch (Exception ex) {
054: ex.printStackTrace();
055: System.exit(0);
056: }
057:
058: }
059:
060: }
061:
062: private static final String usageString = "java "
063: + "examples.shootist.Shootist \n"
064: + ">>>> is your class path set to the root?";
065:
066: private static void usage() {
067: System.out.println(usageString);
068: System.exit(0);
069:
070: }
071:
072: public void processRequest(RequestEvent requestReceivedEvent) {
073: Request request = requestReceivedEvent.getRequest();
074: ServerTransaction serverTransactionId = requestReceivedEvent
075: .getServerTransaction();
076:
077: System.out.println("\n\nRequest " + request.getMethod()
078: + " received at " + sipStack.getStackName()
079: + " with server transaction id " + serverTransactionId);
080:
081: // We are the UAC so the only request we get is the BYE.
082: if (request.getMethod().equals(Request.BYE))
083: processBye(request, serverTransactionId);
084: else {
085: try {
086: serverTransactionId.sendResponse(messageFactory
087: .createResponse(202, request));
088: } catch (SipException e) {
089: // TODO Auto-generated catch block
090: e.printStackTrace();
091: } catch (InvalidArgumentException e) {
092: // TODO Auto-generated catch block
093: e.printStackTrace();
094: } catch (ParseException e) {
095: // TODO Auto-generated catch block
096: e.printStackTrace();
097: }
098: }
099:
100: }
101:
102: public void processBye(Request request,
103: ServerTransaction serverTransactionId) {
104: try {
105: System.out.println("shootist: got a bye .");
106: if (serverTransactionId == null) {
107: System.out.println("shootist: null TID.");
108: return;
109: }
110: Dialog dialog = serverTransactionId.getDialog();
111: System.out.println("Dialog State = " + dialog.getState());
112: Response response = messageFactory.createResponse(200,
113: request);
114: serverTransactionId.sendResponse(response);
115: System.out.println("shootist: Sending OK.");
116: System.out.println("Dialog State = " + dialog.getState());
117:
118: } catch (Exception ex) {
119: ex.printStackTrace();
120: System.exit(0);
121:
122: }
123: }
124:
125: // Save the created ACK request, to respond to retransmitted 2xx
126: private Request ackRequest;
127:
128: public void processResponse(ResponseEvent responseReceivedEvent) {
129: System.out.println("Got a response");
130: Response response = (Response) responseReceivedEvent
131: .getResponse();
132: ClientTransaction tid = responseReceivedEvent
133: .getClientTransaction();
134: CSeqHeader cseq = (CSeqHeader) response
135: .getHeader(CSeqHeader.NAME);
136:
137: System.out.println("Response received : Status Code = "
138: + response.getStatusCode() + " " + cseq);
139:
140: if (tid == null) {
141:
142: // RFC3261: MUST respond to every 2xx
143: if (ackRequest != null && dialog != null) {
144: System.out.println("re-sending ACK");
145: try {
146: dialog.sendAck(ackRequest);
147: } catch (SipException se) {
148: se.printStackTrace();
149: }
150: }
151: return;
152: }
153: // If the caller is supposed to send the bye
154: if (examples.simplecallsetup.Shootme.callerSendsBye
155: && !byeTaskRunning) {
156: byeTaskRunning = true;
157: new Timer().schedule(new ByeTask(dialog), 4000);
158: }
159: System.out.println("transaction state is " + tid.getState());
160: System.out.println("Dialog = " + tid.getDialog());
161: System.out.println("Dialog State is "
162: + tid.getDialog().getState());
163:
164: try {
165: if (response.getStatusCode() == Response.OK) {
166: if (cseq.getMethod().equals(Request.INVITE)) {
167: System.out
168: .println("Dialog after 200 OK " + dialog);
169: System.out.println("Dialog State after 200 OK "
170: + dialog.getState());
171: ackRequest = dialog.createRequest(Request.ACK);
172: System.out.println("Sending ACK");
173: dialog.sendAck(ackRequest);
174:
175: // JvB: test REFER, reported bug in tag handling
176: dialog.sendRequest(sipProvider
177: .getNewClientTransaction(dialog
178: .createRequest("REFER")));
179:
180: } else if (cseq.getMethod().equals(Request.CANCEL)) {
181: if (dialog.getState() == DialogState.CONFIRMED) {
182: // oops cancel went in too late. Need to hang up the
183: // dialog.
184: System.out
185: .println("Sending BYE -- cancel went in too late !!");
186: Request byeRequest = dialog
187: .createRequest(Request.BYE);
188: ClientTransaction ct = sipProvider
189: .getNewClientTransaction(byeRequest);
190: dialog.sendRequest(ct);
191:
192: }
193:
194: }
195: }
196: } catch (Exception ex) {
197: ex.printStackTrace();
198: System.exit(0);
199: }
200:
201: }
202:
203: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
204:
205: System.out.println("Transaction Time out");
206: }
207:
208: public void sendCancel() {
209: try {
210: System.out.println("Sending cancel");
211: Request cancelRequest = inviteTid.createCancel();
212: ClientTransaction cancelTid = sipProvider
213: .getNewClientTransaction(cancelRequest);
214: cancelTid.sendRequest();
215: } catch (Exception ex) {
216: ex.printStackTrace();
217: }
218: }
219:
220: public void init() {
221: SipFactory sipFactory = null;
222: sipStack = null;
223: sipFactory = SipFactory.getInstance();
224: sipFactory.setPathName("gov.nist");
225: Properties properties = new Properties();
226: // If you want to try TCP transport change the following to
227: String transport = "udp";
228: String peerHostPort = "127.0.0.1:5070";
229: properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort
230: + "/" + transport);
231: // If you want to use UDP then uncomment this.
232: properties.setProperty("javax.sip.STACK_NAME", "shootist");
233:
234: // The following properties are specific to nist-sip
235: // and are not necessarily part of any other jain-sip
236: // implementation.
237: // You can set a max message size for tcp transport to
238: // guard against denial of service attack.
239: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
240: "shootistdebug.txt");
241: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
242: "shootistlog.txt");
243:
244: // Drop the client connection after we are done with the transaction.
245: properties.setProperty(
246: "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", "false");
247: // Set to 0 (or NONE) in your production code for max speed.
248: // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for debug + traces.
249: // Your code will limp at 32 but it is best for debugging.
250: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
251: "DEBUG");
252:
253: try {
254: // Create SipStack object
255: sipStack = sipFactory.createSipStack(properties);
256: System.out.println("createSipStack " + sipStack);
257: } catch (PeerUnavailableException e) {
258: // could not find
259: // gov.nist.jain.protocol.ip.sip.SipStackImpl
260: // in the classpath
261: e.printStackTrace();
262: System.err.println(e.getMessage());
263: System.exit(0);
264: }
265:
266: try {
267: headerFactory = sipFactory.createHeaderFactory();
268: addressFactory = sipFactory.createAddressFactory();
269: messageFactory = sipFactory.createMessageFactory();
270: udpListeningPoint = sipStack.createListeningPoint(
271: "127.0.0.1", 5060, "udp");
272: sipProvider = sipStack.createSipProvider(udpListeningPoint);
273: Shootist listener = this ;
274: sipProvider.addSipListener(listener);
275:
276: String fromName = "BigGuy";
277: String fromSipAddress = "here.com";
278: String fromDisplayName = "The Master Blaster";
279:
280: String toSipAddress = "there.com";
281: String toUser = "LittleGuy";
282: String toDisplayName = "The Little Blister";
283:
284: // create >From Header
285: SipURI fromAddress = addressFactory.createSipURI(fromName,
286: fromSipAddress);
287:
288: Address fromNameAddress = addressFactory
289: .createAddress(fromAddress);
290: fromNameAddress.setDisplayName(fromDisplayName);
291: FromHeader fromHeader = headerFactory.createFromHeader(
292: fromNameAddress, "12345");
293:
294: // create To Header
295: SipURI toAddress = addressFactory.createSipURI(toUser,
296: toSipAddress);
297: Address toNameAddress = addressFactory
298: .createAddress(toAddress);
299: toNameAddress.setDisplayName(toDisplayName);
300: ToHeader toHeader = headerFactory.createToHeader(
301: toNameAddress, null);
302:
303: // create Request URI
304: SipURI requestURI = addressFactory.createSipURI(toUser,
305: peerHostPort);
306:
307: // Create ViaHeaders
308:
309: ArrayList viaHeaders = new ArrayList();
310: String ipAddress = udpListeningPoint.getIPAddress();
311: ViaHeader viaHeader = headerFactory.createViaHeader(
312: ipAddress, sipProvider.getListeningPoint(transport)
313: .getPort(), transport, null);
314:
315: // add via headers
316: viaHeaders.add(viaHeader);
317:
318: // Create ContentTypeHeader
319: ContentTypeHeader contentTypeHeader = headerFactory
320: .createContentTypeHeader("application", "sdp");
321:
322: // Create a new CallId header
323: CallIdHeader callIdHeader = sipProvider.getNewCallId();
324:
325: // Create a new Cseq header
326: CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L,
327: Request.INVITE);
328:
329: // Create a new MaxForwardsHeader
330: MaxForwardsHeader maxForwards = headerFactory
331: .createMaxForwardsHeader(70);
332:
333: // Create the request.
334: Request request = messageFactory.createRequest(requestURI,
335: Request.INVITE, callIdHeader, cSeqHeader,
336: fromHeader, toHeader, viaHeaders, maxForwards);
337: // Create contact headers
338: String host = "127.0.0.1";
339:
340: SipURI contactUrl = addressFactory.createSipURI(fromName,
341: host);
342: contactUrl.setPort(udpListeningPoint.getPort());
343: contactUrl.setLrParam();
344:
345: // Create the contact name address.
346: SipURI contactURI = addressFactory.createSipURI(fromName,
347: host);
348: contactURI.setPort(sipProvider.getListeningPoint(transport)
349: .getPort());
350:
351: Address contactAddress = addressFactory
352: .createAddress(contactURI);
353:
354: // Add the contact address.
355: contactAddress.setDisplayName(fromName);
356:
357: contactHeader = headerFactory
358: .createContactHeader(contactAddress);
359: request.addHeader(contactHeader);
360:
361: // You can add extension headers of your own making
362: // to the outgoing SIP request.
363: // Add the extension header.
364: Header extensionHeader = headerFactory.createHeader(
365: "My-Header", "my header value");
366: request.addHeader(extensionHeader);
367:
368: String sdpData = "v=0\r\n"
369: + "o=4855 13760799956958020 13760799956958020"
370: + " IN IP4 129.6.55.78\r\n"
371: + "s=mysession session\r\n"
372: + "p=+46 8 52018010\r\n"
373: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
374: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
375: + "a=rtpmap:0 PCMU/8000\r\n"
376: + "a=rtpmap:4 G723/8000\r\n"
377: + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
378: byte[] contents = sdpData.getBytes();
379:
380: request.setContent(contents, contentTypeHeader);
381: // You can add as many extension headers as you
382: // want.
383:
384: extensionHeader = headerFactory.createHeader(
385: "My-Other-Header", "my new header value ");
386: request.addHeader(extensionHeader);
387:
388: Header callInfoHeader = headerFactory.createHeader(
389: "Call-Info", "<http://www.antd.nist.gov>");
390: request.addHeader(callInfoHeader);
391:
392: // Create the client transaction.
393: inviteTid = sipProvider.getNewClientTransaction(request);
394:
395: // send the request out.
396: inviteTid.sendRequest();
397:
398: dialog = inviteTid.getDialog();
399:
400: } catch (Exception ex) {
401: System.out.println(ex.getMessage());
402: ex.printStackTrace();
403: usage();
404: }
405: }
406:
407: public static void main(String args[]) {
408: new Shootist().init();
409:
410: }
411:
412: public void processIOException(IOExceptionEvent exceptionEvent) {
413: System.out.println("IOException happened for "
414: + exceptionEvent.getHost() + " port = "
415: + exceptionEvent.getPort());
416:
417: }
418:
419: public void processTransactionTerminated(
420: TransactionTerminatedEvent transactionTerminatedEvent) {
421: System.out.println("Transaction terminated event recieved");
422: }
423:
424: public void processDialogTerminated(
425: DialogTerminatedEvent dialogTerminatedEvent) {
426: System.out.println("dialogTerminatedEvent");
427:
428: }
429: }
|