001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package gov.nist.siplite.stack;
027:
028: import gov.nist.core.*;
029: import gov.nist.siplite.header.*;
030: import gov.nist.siplite.message.*;
031:
032: /**
033: * Subscription object.
034: */
035: public class Subscription {
036: /** Reference to the dialog which this subscription belongs to. */
037: private Dialog dialog = null;
038:
039: /** Event header defining this subscription */
040: private EventHeader eventHeader = null;
041:
042: /**
043: * Constructor given a dialog and a request creating the subscription.
044: * @param subscriptionDialog
045: * @param request
046: */
047: public Subscription(Dialog subscriptionDialog, Request request) {
048: // System.out.println("*** Creating a new SUBSCRIPTION, dialog = " +
049: // subscriptionDialog);
050:
051: dialog = subscriptionDialog;
052:
053: if (request.getMethod().equalsIgnoreCase(Request.REFER)) {
054: // RFC 3515, p. 2:
055: // A REFER request implicitly establishes a subscription
056: // to the refer event.
057: eventHeader = new EventHeader();
058: try {
059: eventHeader.setEventType(Request.REFER);
060: } catch (ParseException pe) {
061: // Request.REFER is a valid event type,
062: // so we can't get here.
063: }
064: } else {
065: EventHeader eh = (EventHeader) request
066: .getHeader(Header.EVENT);
067: if (eh != null) {
068: eventHeader = (EventHeader) eh.clone();
069: }
070: }
071: }
072:
073: /**
074: * Return true if the given response message or NOTIFY request matches
075: * this subscription.
076: * @param message a response or NOTIFY request to check for matching
077: * @return true if the given NOTIFY matches this subscription,
078: * false otherwise
079: */
080: public boolean containsSubscription(Message message) {
081: CallIdHeader hCallId = (CallIdHeader) message
082: .getHeader(Header.CALL_ID);
083: if (hCallId == null) {
084: return false;
085: }
086:
087: // Get callId and fromTag from the dialog.
088: CallIdHeader callId = dialog.getCallId();
089: if (callId == null) {
090: return false;
091: }
092:
093: String fromTag = dialog.isServer() ? dialog.getRemoteTag()
094: : dialog.getLocalTag();
095: if (fromTag == null) {
096: return false;
097: }
098:
099: if (message instanceof Response) {
100: /*
101: * RFC3265, section 3.3.4
102: * Responses are matched to such SUBSCRIBE requests if they
103: * contain the same the same "Call-ID", the same "From" header
104: * "tag", and the same "CSeq".
105: *
106: * IMPL_NOTE: compare CSeq
107: */
108: String fTag = message.getFromHeaderTag();
109: if (fTag == null) {
110: return false;
111: }
112:
113: return (hCallId.equals(callId) && fTag
114: .equalsIgnoreCase(fromTag));
115: }
116:
117: /*
118: * RFC 3265, section 3.3.4:
119: * If an initial SUBSCRIBE request is not sent on a pre-existing dialog,
120: * the subscriber will wait for a response to the SUBSCRIBE request or a
121: * matching NOTIFY.
122: *
123: * NOTIFY requests are matched to such SUBSCRIBE requests if they
124: * contain the same "Call-ID", a "To" header "tag" parameter which
125: * matches the "From" header "tag" parameter of the SUBSCRIBE, and the
126: * same "Event" header field.
127: */
128: EventHeader hEvent = (EventHeader) message
129: .getHeader(Header.EVENT);
130: if (hEvent == null) {
131: String reqMethod = ((Request) message).getMethod();
132: if (reqMethod.equalsIgnoreCase(Request.REFER)) {
133: hEvent = eventHeader;
134: } else {
135: return false;
136: }
137: }
138:
139: String toTag = message.getToTag();
140: if (toTag == null) {
141: return false;
142: }
143:
144: return (hEvent.match(eventHeader)
145: && toTag.equalsIgnoreCase(fromTag) && hCallId
146: .equals(callId));
147: }
148: }
|