001: package examples.subsnotify;
002:
003: import gov.nist.javax.sip.stack.SIPTransactionStack;
004:
005: import javax.sip.*;
006: import javax.sip.address.*;
007: import javax.sip.header.*;
008: import javax.sip.message.*;
009:
010: import org.apache.log4j.ConsoleAppender;
011: import org.apache.log4j.FileAppender;
012: import org.apache.log4j.Level;
013: import org.apache.log4j.Logger;
014: import org.apache.log4j.SimpleLayout;
015:
016: import java.util.*;
017:
018: import junit.framework.TestCase;
019:
020: /**
021: * This class is a Subscriber template. Shootist is the guy that shoots and
022: * shootme is the guy that gets shot.
023: *
024: * @author M. Ranganathan
025: */
026:
027: public class Subscriber implements SipListener {
028:
029: private SipProvider sipProvider;
030:
031: private static AddressFactory addressFactory;
032:
033: private static MessageFactory messageFactory;
034:
035: private static HeaderFactory headerFactory;
036:
037: private static SipStack sipStack;
038:
039: private ContactHeader contactHeader;
040:
041: private static String notifierPort;
042:
043: private static String transport;
044:
045: private int count;
046:
047: private Dialog subscriberDialog;
048:
049: private Dialog forkedDialog;
050:
051: private static Logger logger = Logger.getLogger(Subscriber.class);
052:
053: static {
054: try {
055: logger.setLevel(Level.INFO);
056: logger.addAppender(new ConsoleAppender(new SimpleLayout()));
057: logger.addAppender(new FileAppender(new SimpleLayout(),
058: "subscriberoutputlog.txt"));
059: } catch (Exception ex) {
060: throw new RuntimeException(ex);
061: }
062: }
063:
064: private ClientTransaction subscribeTid;
065:
066: private ListeningPoint listeningPoint;
067:
068: protected static final String usageString = "java "
069: + "examples.subsnotify.Subscriber \n"
070: + ">>>> is your class path set to the root?";
071:
072: private static void usage() {
073: logger.info(usageString);
074: System.exit(0);
075:
076: }
077:
078: public void processRequest(RequestEvent requestReceivedEvent) {
079: Request request = requestReceivedEvent.getRequest();
080: ServerTransaction serverTransactionId = requestReceivedEvent
081: .getServerTransaction();
082: String viaBranch = ((ViaHeader) (request
083: .getHeaders(ViaHeader.NAME).next()))
084: .getParameter("branch");
085:
086: logger.info("\n\nRequest " + request.getMethod()
087: + " received at " + sipStack.getStackName()
088: + " with server transaction id " + serverTransactionId
089: + " branch ID = " + viaBranch);
090:
091: if (request.getMethod().equals(Request.NOTIFY))
092: processNotify(requestReceivedEvent, serverTransactionId);
093:
094: }
095:
096: public synchronized void processNotify(RequestEvent requestEvent,
097: ServerTransaction serverTransactionId) {
098: SipProvider provider = (SipProvider) requestEvent.getSource();
099: Request notify = requestEvent.getRequest();
100: try {
101: logger.info("subscriber: got a notify count "
102: + this .count++);
103: if (serverTransactionId == null) {
104: logger.info("subscriber: null TID.");
105: serverTransactionId = provider
106: .getNewServerTransaction(notify);
107: }
108: Dialog dialog = serverTransactionId.getDialog();
109: logger.info("Dialog = " + dialog);
110:
111: if (dialog != null) {
112: logger.info("Dialog State = " + dialog.getState());
113: }
114:
115: if (dialog != subscriberDialog) {
116: if (forkedDialog == null) {
117: forkedDialog = dialog;
118: } else {
119: if (forkedDialog != dialog) {
120: System.out.println("dialog = " + dialog);
121: System.out.println("forkedDialog "
122: + forkedDialog);
123: System.out.println("subscribedialog = "
124: + this .subscriberDialog);
125: ((SIPTransactionStack) sipStack)
126: .printDialogTable();
127: }
128: TestCase
129: .assertTrue(
130: "Dialog should be either the subscriber dialog ",
131: forkedDialog == dialog);
132: }
133: }
134:
135: Response response = messageFactory.createResponse(200,
136: notify);
137: // SHOULD add a Contact
138: ContactHeader contact = (ContactHeader) contactHeader
139: .clone();
140: ((SipURI) contact.getAddress().getURI()).setParameter("id",
141: "sub");
142: response.addHeader(contact);
143: logger.info("Transaction State = "
144: + serverTransactionId.getState());
145: serverTransactionId.sendResponse(response);
146: if (dialog != null) {
147: logger.info("Dialog State = " + dialog.getState());
148: }
149: SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) notify
150: .getHeader(SubscriptionStateHeader.NAME);
151:
152: // Subscription is terminated?
153: String state = subscriptionState.getState();
154: if (state
155: .equalsIgnoreCase(SubscriptionStateHeader.TERMINATED)) {
156: dialog.delete();
157: } else {
158: logger.info("Subscriber: state now " + state);
159: }
160:
161: } catch (Exception ex) {
162: ex.printStackTrace();
163: logger.error("Unexpected exception", ex);
164: System.exit(0);
165:
166: }
167: }
168:
169: public void processResponse(ResponseEvent responseReceivedEvent) {
170: logger.info("Got a response");
171: Response response = (Response) responseReceivedEvent
172: .getResponse();
173: Transaction tid = responseReceivedEvent.getClientTransaction();
174:
175: logger.info("Response received with client transaction id "
176: + tid + ":\n" + response.getStatusCode());
177: if (tid == null) {
178: logger.info("Stray response -- dropping ");
179: return;
180: }
181: logger.info("transaction state is " + tid.getState());
182: logger.info("Dialog = " + tid.getDialog());
183: if (tid.getDialog() != null)
184: logger
185: .info("Dialog State is "
186: + tid.getDialog().getState());
187:
188: }
189:
190: public void createProvider() throws Exception {
191:
192: this .listeningPoint = sipStack.createListeningPoint(
193: "127.0.0.1", 5060, transport);
194: sipProvider = sipStack.createSipProvider(listeningPoint);
195:
196: }
197:
198: public void sendSubscribe() {
199:
200: try {
201:
202: String fromName = "BigGuy";
203: String fromSipAddress = "here.com";
204: String fromDisplayName = "The Master Blaster";
205:
206: String toSipAddress = "there.com";
207: String toUser = "LittleGuy";
208: String toDisplayName = "The Little Blister";
209:
210: // create >From Header
211: SipURI fromAddress = addressFactory.createSipURI(fromName,
212: fromSipAddress);
213:
214: Address fromNameAddress = addressFactory
215: .createAddress(fromAddress);
216: fromNameAddress.setDisplayName(fromDisplayName);
217: FromHeader fromHeader = headerFactory.createFromHeader(
218: fromNameAddress, "12345");
219:
220: // create To Header
221: SipURI toAddress = addressFactory.createSipURI(toUser,
222: toSipAddress);
223: Address toNameAddress = addressFactory
224: .createAddress(toAddress);
225: toNameAddress.setDisplayName(toDisplayName);
226: ToHeader toHeader = headerFactory.createToHeader(
227: toNameAddress, null);
228:
229: // create Request URI
230: SipURI requestURI = addressFactory.createSipURI(toUser,
231: toSipAddress);
232:
233: // Create ViaHeaders
234:
235: ArrayList viaHeaders = new ArrayList();
236: int port = sipProvider.getListeningPoint(transport)
237: .getPort();
238: ViaHeader viaHeader = headerFactory.createViaHeader(
239: "127.0.0.1", port, transport, null);
240:
241: // add via headers
242: viaHeaders.add(viaHeader);
243:
244: // Create a new CallId header
245: CallIdHeader callIdHeader = sipProvider.getNewCallId();
246:
247: // Create a new Cseq header
248: CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L,
249: Request.SUBSCRIBE);
250:
251: // Create a new MaxForwardsHeader
252: MaxForwardsHeader maxForwards = headerFactory
253: .createMaxForwardsHeader(70);
254:
255: // Create the request.
256: Request request = messageFactory.createRequest(requestURI,
257: Request.SUBSCRIBE, callIdHeader, cSeqHeader,
258: fromHeader, toHeader, viaHeaders, maxForwards);
259: // Create contact headers
260: String host = listeningPoint.getIPAddress();
261:
262: SipURI contactUrl = addressFactory.createSipURI(fromName,
263: host);
264: contactUrl.setPort(listeningPoint.getPort());
265:
266: // Create the contact name address.
267: SipURI contactURI = addressFactory.createSipURI(fromName,
268: host);
269: contactURI.setTransportParam(transport);
270: contactURI.setPort(sipProvider.getListeningPoint(transport)
271: .getPort());
272:
273: Address contactAddress = addressFactory
274: .createAddress(contactURI);
275:
276: // Add the contact address.
277: contactAddress.setDisplayName(fromName);
278:
279: contactHeader = headerFactory
280: .createContactHeader(contactAddress);
281: request.addHeader(contactHeader);
282:
283: // JvB: To test forked SUBSCRIBEs, send it via the Forker
284: // Note: BIG Gotcha: Need to do this before creating the
285: // ClientTransaction!
286:
287: RouteHeader route = headerFactory
288: .createRouteHeader(addressFactory
289: .createAddress("<sip:127.0.0.1:"
290: + notifierPort + ";transport="
291: + transport + ";lr>"));
292: request.addHeader(route);
293: // JvB end added
294:
295: // Create the client transaction.
296: subscribeTid = sipProvider.getNewClientTransaction(request);
297:
298: // Create an event header for the subscription.
299: EventHeader eventHeader = headerFactory
300: .createEventHeader("foo");
301: eventHeader.setEventId("foo");
302: request.addHeader(eventHeader);
303:
304: logger.info("Subscribe Dialog = "
305: + subscribeTid.getDialog());
306:
307: this .subscriberDialog = subscribeTid.getDialog();
308: // send the request out.
309: subscribeTid.sendRequest();
310:
311: } catch (Throwable ex) {
312: logger.info(ex.getMessage());
313: ex.printStackTrace();
314: usage();
315: }
316: }
317:
318: public static void main(String args[]) throws Exception {
319: // 5065 sends to the forker.
320: // 5070 sends to the subscriber1
321:
322: notifierPort = args[0];
323:
324: transport = "udp";
325:
326: SipFactory sipFactory = SipFactory.getInstance();
327: sipFactory.setPathName("gov.nist");
328: Properties properties = new Properties();
329:
330: properties.setProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS",
331: "false");
332:
333: properties.setProperty("javax.sip.STACK_NAME", "subscriber");
334: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
335: "subscriberdebug.txt");
336: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
337: "subscriberlog.txt");
338:
339: properties.setProperty("javax.sip.FORKABLE_EVENTS", "foo");
340:
341: // Set to 0 in your production code for max speed.
342: // You need 16 for logging traces. 32 for debug + traces.
343: // Your code will limp at 32 but it is best for debugging.
344: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
345:
346: sipStack = sipFactory.createSipStack(properties);
347: logger.info("createSipStack " + sipStack);
348: headerFactory = sipFactory.createHeaderFactory();
349: addressFactory = sipFactory.createAddressFactory();
350: messageFactory = sipFactory.createMessageFactory();
351:
352: Subscriber subscriber = new Subscriber();
353: subscriber.createProvider();
354: subscriber.sipProvider.addSipListener(subscriber);
355: subscriber.sendSubscribe();
356:
357: }
358:
359: public void processIOException(IOExceptionEvent exceptionEvent) {
360: logger.info("io exception event recieved");
361: }
362:
363: public void processTransactionTerminated(
364: TransactionTerminatedEvent transactionTerminatedEvent) {
365:
366: }
367:
368: public void processDialogTerminated(
369: DialogTerminatedEvent dialogTerminatedEvent) {
370: logger.info("dialog terminated event recieved");
371: }
372:
373: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
374:
375: logger.info("Transaction Time out");
376: }
377: }
|