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 Shootist extends TestCase implements SipListener {
025:
026: private ContactHeader contactHeader;
027:
028: private ClientTransaction inviteTid;
029:
030: private int count;
031:
032: private SipProvider sipProvider;
033:
034: private String host = "127.0.0.1";
035:
036: private int port = 5060;
037:
038: private String peerHost = "127.0.0.1";
039:
040: private int peerPort = 5070;
041:
042: private String transport = "udp";
043:
044: private ListeningPoint listeningPoint;
045:
046: private static String unexpectedException = "Unexpected exception ";
047:
048: private static Logger logger = Logger.getLogger(Shootist.class);
049:
050: private Dialog dialog;
051:
052: static {
053: try {
054: logger.addAppender(new FileAppender(new SimpleLayout(),
055: ProtocolObjects.logFileDirectory
056: + "shootistconsolelog.txt"));
057: } catch (Exception ex) {
058: throw new RuntimeException(
059: "could not open shootistconsolelog.txt");
060: }
061: }
062:
063: public void processRequest(RequestEvent requestReceivedEvent) {
064: Request request = requestReceivedEvent.getRequest();
065: ServerTransaction serverTransactionId = requestReceivedEvent
066: .getServerTransaction();
067:
068: logger.info("\n\nRequest " + request.getMethod()
069: + " received at shootist "
070: + " with server transaction id " + serverTransactionId);
071:
072: // We are the UAC so the only request we get is the BYE.
073: if (request.getMethod().equals(Request.BYE))
074: processBye(request, serverTransactionId);
075: else
076: fail("Unexpected request ! : " + request);
077:
078: }
079:
080: public void processBye(Request request,
081: ServerTransaction serverTransactionId) {
082: try {
083: logger.info("shootist: got a bye .");
084: if (serverTransactionId == null) {
085: logger.info("shootist: null TID.");
086: return;
087: }
088: Dialog dialog = serverTransactionId.getDialog();
089: logger.info("Dialog State = " + dialog.getState());
090: Response response = ProtocolObjects.messageFactory
091: .createResponse(200, request);
092: serverTransactionId.sendResponse(response);
093: logger.info("shootist: Sending OK.");
094: logger.info("Dialog State = " + dialog.getState());
095:
096: } catch (Exception ex) {
097: ex.printStackTrace();
098: System.exit(0);
099:
100: }
101: }
102:
103: public synchronized void processResponse(
104: ResponseEvent responseReceivedEvent) {
105: logger.info("Got a response");
106: Response response = (Response) responseReceivedEvent
107: .getResponse();
108: ClientTransaction tid = responseReceivedEvent
109: .getClientTransaction();
110: CSeqHeader cseq = (CSeqHeader) response
111: .getHeader(CSeqHeader.NAME);
112:
113: logger.info("Response received : Status Code = "
114: + response.getStatusCode() + " " + cseq);
115:
116: Dialog dialog = responseReceivedEvent.getDialog();
117:
118: if (tid != null)
119: logger.info("transaction state is " + tid.getState());
120: else
121: logger.info("transaction = " + tid);
122:
123: logger.info("Dialog = " + dialog);
124:
125: if (dialog != null) {
126: logger.info("Dialog state is " + dialog.getState());
127: } else {
128: logger.info("Dialog is null -- ignoring response!");
129: return;
130: }
131:
132: try {
133: if (response.getStatusCode() == Response.OK) {
134: if (cseq.getMethod().equals(Request.INVITE)) {
135: Request ackRequest = dialog.createAck(cseq
136: .getSeqNumber());
137: logger.info("dialog = " + dialog);
138:
139: // Proxy will fork. I will accept the second dialog
140: // but not the first.
141: logger.info("count = " + count);
142: if (count == 1) {
143: //assertTrue(dialog != this.dialog);
144: logger.info("Sending ACK");
145: dialog.sendAck(ackRequest);
146: assertTrue(dialog.getState() == DialogState.CONFIRMED);
147:
148: } else {
149: // Kill the first dialog by sending a bye.
150: //assertTrue (dialog == this.dialog);
151: count++;
152: logger.info("count = " + count);
153: dialog.sendAck(ackRequest);
154: SipProvider sipProvider = (SipProvider) responseReceivedEvent
155: .getSource();
156: Request byeRequest = dialog
157: .createRequest(Request.BYE);
158: ClientTransaction ct = sipProvider
159: .getNewClientTransaction(byeRequest);
160: dialog.sendRequest(ct);
161: }
162:
163: } else {
164: logger
165: .info("Response method = "
166: + cseq.getMethod());
167: }
168: }
169: } catch (Exception ex) {
170: ex.printStackTrace();
171: System.exit(0);
172: }
173:
174: }
175:
176: public SipProvider createSipProvider() {
177: try {
178: listeningPoint = ProtocolObjects.sipStack
179: .createListeningPoint(host, port, transport);
180:
181: sipProvider = ProtocolObjects.sipStack
182: .createSipProvider(listeningPoint);
183: return sipProvider;
184: } catch (Exception ex) {
185: logger.error(unexpectedException, ex);
186: fail(unexpectedException);
187: return null;
188: }
189:
190: }
191:
192: public boolean checkState() {
193: return this .count == 1;
194: }
195:
196: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
197:
198: logger.info("Transaction Time out");
199: }
200:
201: public void sendInvite() {
202: try {
203:
204: String fromName = "BigGuy";
205: String fromSipAddress = "here.com";
206: String fromDisplayName = "The Master Blaster";
207:
208: String toSipAddress = "there.com";
209: String toUser = "LittleGuy";
210: String toDisplayName = "The Little Blister";
211:
212: // create >From Header
213: SipURI fromAddress = ProtocolObjects.addressFactory
214: .createSipURI(fromName, fromSipAddress);
215:
216: Address fromNameAddress = ProtocolObjects.addressFactory
217: .createAddress(fromAddress);
218: fromNameAddress.setDisplayName(fromDisplayName);
219: FromHeader fromHeader = ProtocolObjects.headerFactory
220: .createFromHeader(fromNameAddress, "12345");
221:
222: // create To Header
223: SipURI toAddress = ProtocolObjects.addressFactory
224: .createSipURI(toUser, toSipAddress);
225: Address toNameAddress = ProtocolObjects.addressFactory
226: .createAddress(toAddress);
227: toNameAddress.setDisplayName(toDisplayName);
228: ToHeader toHeader = ProtocolObjects.headerFactory
229: .createToHeader(toNameAddress, null);
230:
231: // create Request URI
232: String peerHostPort = peerHost + ":" + peerPort;
233: SipURI requestURI = ProtocolObjects.addressFactory
234: .createSipURI(toUser, peerHostPort);
235:
236: // Create ViaHeaders
237:
238: ArrayList viaHeaders = new ArrayList();
239: ViaHeader viaHeader = ProtocolObjects.headerFactory
240: .createViaHeader(host, sipProvider
241: .getListeningPoint(transport).getPort(),
242: transport, null);
243:
244: // add via headers
245: viaHeaders.add(viaHeader);
246:
247: SipURI sipuri = ProtocolObjects.addressFactory
248: .createSipURI(null, host);
249: sipuri.setPort(peerPort);
250: sipuri.setLrParam();
251:
252: RouteHeader routeHeader = ProtocolObjects.headerFactory
253: .createRouteHeader(ProtocolObjects.addressFactory
254: .createAddress(sipuri));
255:
256: // Create ContentTypeHeader
257: ContentTypeHeader contentTypeHeader = ProtocolObjects.headerFactory
258: .createContentTypeHeader("application", "sdp");
259:
260: // Create a new CallId header
261: CallIdHeader callIdHeader = sipProvider.getNewCallId();
262:
263: // Create a new Cseq header
264: CSeqHeader cSeqHeader = ProtocolObjects.headerFactory
265: .createCSeqHeader(1L, Request.INVITE);
266:
267: // Create a new MaxForwardsHeader
268: MaxForwardsHeader maxForwards = ProtocolObjects.headerFactory
269: .createMaxForwardsHeader(70);
270:
271: // Create the request.
272: Request request = ProtocolObjects.messageFactory
273: .createRequest(requestURI, Request.INVITE,
274: callIdHeader, cSeqHeader, fromHeader,
275: toHeader, viaHeaders, maxForwards);
276: // Create contact headers
277:
278: SipURI contactUrl = ProtocolObjects.addressFactory
279: .createSipURI(fromName, host);
280: contactUrl.setPort(listeningPoint.getPort());
281:
282: // Create the contact name address.
283: SipURI contactURI = ProtocolObjects.addressFactory
284: .createSipURI(fromName, host);
285: contactURI.setPort(sipProvider.getListeningPoint("udp")
286: .getPort());
287:
288: Address contactAddress = ProtocolObjects.addressFactory
289: .createAddress(contactURI);
290:
291: // Add the contact address.
292: contactAddress.setDisplayName(fromName);
293:
294: contactHeader = ProtocolObjects.headerFactory
295: .createContactHeader(contactAddress);
296: request.addHeader(contactHeader);
297:
298: // Dont use the Outbound Proxy. Use Lr instead.
299: request.setHeader(routeHeader);
300:
301: // Add the extension header.
302: Header extensionHeader = ProtocolObjects.headerFactory
303: .createHeader("My-Header", "my header value");
304: request.addHeader(extensionHeader);
305:
306: String sdpData = "v=0\r\n"
307: + "o=4855 13760799956958020 13760799956958020"
308: + " IN IP4 129.6.55.78\r\n"
309: + "s=mysession session\r\n"
310: + "p=+46 8 52018010\r\n"
311: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
312: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
313: + "a=rtpmap:0 PCMU/8000\r\n"
314: + "a=rtpmap:4 G723/8000\r\n"
315: + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
316: byte[] contents = sdpData.getBytes();
317:
318: request.setContent(contents, contentTypeHeader);
319:
320: extensionHeader = ProtocolObjects.headerFactory
321: .createHeader("My-Other-Header",
322: "my new header value ");
323: request.addHeader(extensionHeader);
324:
325: Header callInfoHeader = ProtocolObjects.headerFactory
326: .createHeader("Call-Info",
327: "<http://www.antd.nist.gov>");
328: request.addHeader(callInfoHeader);
329:
330: // Create the client transaction.
331: inviteTid = sipProvider.getNewClientTransaction(request);
332:
333: // send the request out.
334: inviteTid.sendRequest();
335:
336: this .dialog = inviteTid.getDialog();
337:
338: assertTrue(dialog.getState() == null);
339: assertTrue(inviteTid.getState() == TransactionState.CALLING);
340:
341: } catch (Exception ex) {
342: logger.error(unexpectedException, ex);
343: fail(unexpectedException);
344:
345: }
346: }
347:
348: public static void main(String args[]) throws Exception {
349: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
350: ProtocolObjects.init("shootist", true);
351: Shootist shootist = new Shootist();
352: shootist.createSipProvider();
353: shootist.sipProvider.addSipListener(shootist);
354: shootist.sendInvite();
355:
356: }
357:
358: public void processIOException(IOExceptionEvent exceptionEvent) {
359: logger.info("IOException happened for "
360: + exceptionEvent.getHost() + " port = "
361: + exceptionEvent.getPort());
362:
363: }
364:
365: public void processTransactionTerminated(
366: TransactionTerminatedEvent transactionTerminatedEvent) {
367: logger.info("Transaction terminated event recieved");
368: }
369:
370: public void processDialogTerminated(
371: DialogTerminatedEvent dialogTerminatedEvent) {
372: logger.info("dialogTerminatedEvent");
373:
374: }
375: }
|