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 }