1 /*
2 * jSDP: A Java implementation of SDP protocol Copyright (C) 2007 Claudio Di
3 * Vita
4 */
5 package net.sourceforge.jsdp;
6
7 import java.util.regex.Matcher;
8 import java.util.regex.Pattern;
9
10 /**
11 * A <tt>Bandwith</tt> represents an <b>b=<i><field value></i></b>
12 * field contained in a SDP message.
13 * <p>
14 * A bandwith field specifies the proposed bandwidth to be used by the session
15 * or media, and is optional. Multiple bandwidth specifiers of different types
16 * may be associated with the same {@link SessionDescription}. Each has the
17 * form <b>b<i>=<modifier></i>:<i><value></i></b>. There are
18 * four bandwith modifers (or types):
19 * </p>
20 * <ul>
21 * <li>AS: Application Specific maximum. The bandwidth is interpreted to be
22 * application-specific, and will be treated as application's concept of maximum
23 * bandwidth</li>
24 * <br/>
25 * <li>CT: Conference Total. An implicit maximum bandwidth is associated with
26 * each TTL on the Mbone or within a particular multicast administrative scope
27 * region (the Mbone bandwidth vs. TTL limits are given in the MBone FAQ). If
28 * the bandwidth of a session or media in a session is different from the
29 * bandwidth implicit from the scope, a <b>b=CT:<i><bandwith></i></b>
30 * line should be supplied for the session giving the proposed upper limit to
31 * the bandwidth used.<br/>The primary purpose of this is to give an
32 * approximate idea as to whether two or more conferences can co-exist
33 * simultaneously</li>
34 * <br/>
35 * <li>RS: RCTP bandwith for data senders</li>
36 * <br/>
37 * <li>RR: RCTP bandwith for other participants in the RTP session</li>
38 * </ul>
39 *
40 * @since 0.1.0
41 *
42 * @version 1.0
43 *
44 * @author <a href="mailto:cdivita@users.sourceforge.net">Claudio Di Vita</a>
45 */
46 public class Bandwith implements Field {
47
48 /** The class Stream Unique Identifier, SUID */
49 private static final long serialVersionUID = 8829981734747249624L;
50
51 /** The AS modifier */
52 public static final String AS = "AS";
53
54 /** The CT modifier */
55 public static final String CT = "CT";
56
57 /** The RS modifier */
58 public static final String RS = "RS";
59
60 /** The RR modifier */
61 public static final String RR = "RR";
62
63 /** The pattern used to parse the field */
64 private static final Pattern fieldPattern = Pattern.compile("(.+):((\\d+))");
65
66 /** The bandwith modifier */
67 protected String modifier;
68
69 /** The bandwith value, in kbits/second */
70 protected int value;
71
72 /**
73 * Creates a new <tt>Bandwith</tt>.
74 */
75 protected Bandwith() {
76
77 super();
78 }
79
80 /**
81 * Creates a new <tt>Bandwith</tt>.
82 *
83 * @param modifier the bandwith modifier
84 * @param value the bandwith value in kbits/second
85 *
86 * @throws SDPException if the modifier is unknown, or the value is negative
87 */
88 public Bandwith(final String modifier, final int value) throws SDPException {
89
90 this();
91
92 setModifier(modifier);
93 setValue(value);
94 }
95
96 /**
97 * Parse an input string and constructs the equivalent bandwith field.
98 *
99 * @param field the string to parse
100 *
101 * @return a new <tt>Bandwith</tt> instance
102 *
103 * @throws SDPParseException if an error occurs while parsing
104 */
105 public static Bandwith parse(final String field) throws SDPParseException {
106
107 if (!field.startsWith("b=")) {
108 throw new SDPParseException("The string \"" + field + "\" isn't a bandwith field");
109 }
110
111 Bandwith b = null;
112
113 /* Create the matcher */
114 Matcher matcher = fieldPattern.matcher(field.substring(2));
115
116 /* Test */
117 if (matcher.matches()) {
118 try {
119 b = new Bandwith(matcher.group(1), Integer.parseInt(matcher.group(2)));
120 }
121 catch (SDPException parseException) {
122 throw new SDPParseException("The string \"" + field + "\" isn't a valid bandwith field", parseException);
123 }
124 }
125 else {
126 throw new SDPParseException("The string \"" + field + "\" isn't a valid bandwith field");
127 }
128
129 return b;
130 }
131
132 /**
133 * Returns a clone of this field.
134 *
135 * @return a clone of this field
136 */
137 public Object clone() {
138
139 Bandwith field = new Bandwith();
140 field.modifier = new String(modifier);
141 field.value = this.value;
142
143 return field;
144 }
145
146 /**
147 * Returns the bandwith modifier.
148 *
149 * @return The bandwith modifier.
150 * <p>
151 * The allowed modifiers are defined by <a
152 * href="http://www.ietf.org/rfc/rfc2327.txt">RFC 2327</a> and <a
153 * href="http://www.ietf.org/rfc/rfc3556.txt">RFC 3556</a>:
154 * </p>
155 * <ul>
156 * <li>AS: Application Specific</li>
157 * <li>CT: Conference Total</li>
158 * <li>RS: RCTP bandwith for data senders</li>
159 * <li>RR: RCTP bandwith for data receivers</li>
160 * </ul>
161 */
162 public String getModifier() {
163
164 return modifier;
165 }
166
167 /**
168 * Returns the type character for the field.
169 *
170 * @return the field type character: <b>b</b>
171 */
172 public char getType() {
173
174 return Field.BANDWITH_FIELD;
175 }
176
177 /**
178 * Returns the bandwith value.
179 *
180 * @return the bandwith value in kbits/second
181 */
182 public int getValue() {
183
184 return value;
185 }
186
187 /**
188 * Sets the bandwith modifier.
189 *
190 * @param modifier the modifier to set
191 *
192 * @throws SDPException if the modifier is unknown
193 */
194 public void setModifier(final String modifier) throws SDPException {
195
196 if (modifier.equals(AS) || modifier.equals(CT) || modifier.equals(RR) || modifier.equals(RS)) {
197 this.modifier = modifier;
198 }
199 else {
200 throw new SDPException("Unknown modifier: " + modifier);
201 }
202 }
203
204 /**
205 * Sets the bandwith value.
206 *
207 * @param value the value to set
208 *
209 * @throws SDPException if value is negative
210 */
211 public void setValue(final int value) throws SDPException {
212
213 if (value < 0) {
214 throw new SDPException("Invalid bandwith value: " + value);
215 }
216
217 this.value = value;
218 }
219
220 /**
221 * Returns a string representation of the field. The representation has the
222 * form: <b>b=<i><modifier></i>:<i><value></i></b>
223 *
224 * @return the string representation of the field
225 */
226 public String toString() {
227
228 return getType() + "=" + modifier + ":" + value;
229 }
230 }