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