| /* |
| * Conditions Of Use |
| * |
| * This software was developed by employees of the National Institute of |
| * Standards and Technology (NIST), an agency of the Federal Government. |
| * Pursuant to title 15 Untied States Code Section 105, works of NIST |
| * employees are not subject to copyright protection in the United States |
| * and are considered to be in the public domain. As a result, a formal |
| * license is not needed to use the software. |
| * |
| * This software is provided by NIST as a service and is expressly |
| * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED |
| * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT |
| * AND DATA ACCURACY. NIST does not warrant or make any representations |
| * regarding the use of the software or the results thereof, including but |
| * not limited to the correctness, accuracy, reliability or usefulness of |
| * the software. |
| * |
| * Permission to use this software is contingent upon your acceptance |
| * of the terms of this agreement |
| * |
| * . |
| * |
| */ |
| /***************************************************************************** |
| * PRODUCT OF PT INOVACAO - EST DEPARTMENT and Aveiro University - Portugal) * |
| *****************************************************************************/ |
| |
| |
| package gov.nist.javax.sdp.fields; |
| |
| |
| import java.util.Vector; |
| import javax.sdp.SdpException; |
| import javax.sdp.SdpParseException; |
| import gov.nist.core.NameValue; |
| |
| |
| |
| |
| /** |
| * Precondition fields (segmented / end-to-end). |
| * |
| * <p>For one media description, precondition attributes should |
| * be only of one type (segmented or end-to-end) </p> |
| * <p>3GPP TS 24.299, </p> |
| * IETF RFC3312 + RFC4032 (Precondition Mechanism). |
| * |
| * @author Miguel Freitas (IT) PT-Inovacao |
| */ |
| |
| |
| public class PreconditionFields |
| { |
| |
| // Media Description attributes for precondition |
| protected Vector preconditionAttributes; |
| |
| |
| /** |
| * Constructor |
| * |
| */ |
| public PreconditionFields() |
| { |
| preconditionAttributes = new Vector(); |
| } |
| |
| |
| /** |
| * Get the number of Precondition attributes |
| * |
| * @return int size of segmented precondition vector of attribute fields |
| */ |
| public int getPreconditionSize() |
| { |
| if (preconditionAttributes != null) |
| return preconditionAttributes.size(); |
| |
| else // TODO treat this exception well |
| return -1; |
| } |
| |
| /** |
| * Get Precondition |
| * |
| * @return Vector of attribute fields (segmented precondition) |
| */ |
| public Vector getPreconditions() |
| { |
| return preconditionAttributes; |
| } |
| |
| |
| /** |
| * Set Preconditions |
| * |
| * @param preconditions - vector with precondition attributes |
| * @throws SdpException -- if precondition attributes is null |
| */ |
| public void setPreconditions(Vector preconditions) throws SdpException |
| { |
| if (preconditions == null) |
| throw new SdpException("Precondition attributes are null"); |
| else |
| preconditionAttributes = preconditions; |
| } |
| |
| |
| |
| /** |
| * <p>Set attribute line for current precondition state, given |
| * a string value encoded like the "curr" attribute value</p> |
| * |
| * @param precondCurrValue - a string with the value for a "curr" attribute |
| * @throws SdpException |
| */ |
| public void setPreconditionCurr(String precondCurrValue) throws SdpException |
| { |
| if (precondCurrValue == null) |
| throw new SdpException("The Precondition \"curr\" attribute value is null"); |
| else if (preconditionAttributes == null) |
| throw new SdpException("The Precondition Attributes is null"); |
| else |
| { |
| try |
| { |
| /* split the "curr" attribute value into words |
| * attributes[0] = "qos" |
| * attributes[1] = status-type (e2e/local/remote) |
| * attributes[2] = direction-tag (none/send/recv/sendrecv) |
| * |
| * split() - regular expression: |
| * \s -> a whitespace character [ \t\n\x0B\f\r] |
| * \b -> a word boundary |
| */ |
| String[] attributes = precondCurrValue.split(" "); |
| |
| |
| // which is this length?! of the string or the []? |
| /* |
| if (attributes.length < 3) |
| { |
| throw new SdpException |
| ("The Precondition \"curr\" attribute value mal-formed (<3words)"); |
| }*/ |
| |
| setPreconditionCurr(attributes[1], // status-type |
| attributes[2] // direction-tag |
| ); |
| } |
| catch (ArrayIndexOutOfBoundsException ex) |
| { |
| throw new SdpException |
| ("Error spliting the \"curr\" attribute into words", ex); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| /** |
| * <p>Set the value of the attributes with the name "curr" |
| * for current precondition.</p> |
| * <p>- eg: a=curr:qos local none</p> |
| * |
| * <p>If there is an attribute "curr" for the same status-type, |
| * the direction-tag is updated with the one supplied.</p> |
| * |
| * @param status - (local, remote, e2e) |
| * @param directionTag - (none, send, recv, sendrecv) |
| * @throws SdpParseException |
| */ |
| public void setPreconditionCurr(String status, String directionTag) |
| throws SdpException |
| { |
| if (status == null) |
| throw new SdpException("The status-type is null"); |
| if (directionTag == null) |
| throw new SdpException("The direction-tag is null"); |
| |
| if (preconditionAttributes == null) |
| throw new SdpException("Precondition Attributes is null"); |
| |
| int i = 0; |
| // search for attributes "curr" |
| for (i = 0; i < preconditionAttributes.size(); i++) |
| { |
| AttributeField af = |
| (AttributeField) this.preconditionAttributes.elementAt(i); |
| |
| // go to next attribute if this is not "curr" |
| if (!af.getAttribute().getName().equals("curr")) |
| continue; |
| |
| // if it is "curr" attribute, check the status-type |
| // if it matches the value supplied, update the direction-tag |
| // with the value supplied |
| if (af.getValue().indexOf(status) != -1) |
| { |
| if (af.getValue().indexOf(directionTag) == -1) |
| { |
| // attribute exists with same status, directionTag updated |
| af.setValue("qos " + status + " " + directionTag); |
| preconditionAttributes.setElementAt(af,i); |
| } |
| // else, exit and do nothing (attribute already exists) |
| else |
| break; |
| } |
| } |
| |
| // attribute "curr" not found |
| if (i == preconditionAttributes.size()) |
| { |
| // create attribute for the status-type supplied |
| NameValue nv = new NameValue("curr", "qos " + status + " " + directionTag); |
| |
| AttributeField newAF = new AttributeField(); |
| newAF.setAttribute(nv); |
| preconditionAttributes.add(newAF); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| /** |
| * <p>Set attribute line for desired precondition state, given |
| * a string value encoded like the "des" attribute value</p> |
| * |
| * @param precondDesValue - a string with the value for a "des" attribute |
| * @throws SdpException |
| */ |
| public void setPreconditionDes(String precondDesValue) throws SdpException |
| { |
| if (precondDesValue == null) |
| throw new SdpException("The Precondition \"des\" attribute value is null"); |
| else if (preconditionAttributes == null) |
| throw new SdpException("The Precondition Attributes is null"); |
| else |
| { |
| /* split the "des" attribute value into words |
| * attributes[0] = "qos" |
| * attributes[1] = strength-tag (unknown/failure/none/optional/mandatory) |
| * attributes[2] = status-type (e2e/local/remote) |
| * attributes[3] = direction-tag (none/send/recv/sendrecv) |
| * |
| * split() - regular expression: |
| * \s -> a whitespace character [ \t\n\x0B\f\r] |
| * \b -> a word boundary |
| */ |
| try |
| { |
| String[] attributes = precondDesValue.split(" "); |
| |
| // which is this length?! of the string or the []? |
| /* |
| if (attributes.length < 4) |
| { |
| throw new SdpException |
| ("The Precondition \"des\" attribute value mal-formed (<4words)"); |
| }*/ |
| |
| setPreconditionDes( attributes[1], // strength-tag |
| attributes[2], // status-type |
| attributes[3] // direction-tag |
| ); |
| } |
| catch (ArrayIndexOutOfBoundsException ex) |
| { |
| throw new SdpException |
| ("Error spliting the \"des\" attribute into words", ex); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| /** |
| * <p>Set the value of the attributes with the name "des" |
| * for desired precondition. </p> |
| * <p>- eg: a=des:qos mandatory remote sendrecv</p> |
| * |
| * <p>There can be more than one desired precondition line |
| * for a status-type, specially if strength-tag is different.</p> |
| * |
| * <p>If there is an attribute "des" for the same status-type, |
| * the strength-tag and direction-tag are updated with the |
| * ones supplied.<p> |
| * |
| * <p>IETF RFC4032: strength should only be downgraded within SDP offers</p> |
| * |
| * |
| * @param strength - (none, optional, |
| * @param status - (local, remote, e2e) |
| * @param direction - (none, send, recv, sendrecv) |
| * @throws SdpParseException |
| */ |
| public void setPreconditionDes(String strength, String status, String direction) |
| throws SdpException |
| { |
| if (strength == null) |
| throw new SdpException("The strength-tag is null"); |
| if (status == null) |
| throw new SdpException("The status-type is null"); |
| if (direction == null) |
| throw new SdpException("The direction-tag is null"); |
| |
| if (preconditionAttributes == null) |
| throw new SdpException("Precondition Attributes is null"); |
| |
| int i = 0; |
| // search for attributes "des" |
| for (i = 0; i < preconditionAttributes.size(); i++) |
| { |
| AttributeField af = |
| (AttributeField) this.preconditionAttributes.elementAt(i); |
| |
| // go to next attribute if this is not "des" |
| if (!af.getAttribute().getName().equals("des")) |
| continue; |
| |
| // if it is "des" attribute, check the status-type |
| // if it match, update the strength-tag and direction-tag |
| if (af.getValue().indexOf(status) != -1) |
| { |
| // attribute exists with same status-type, |
| // strength-tag and direction-tag updated |
| af.setValue("qos " + strength + " " + status + " " + direction); |
| preconditionAttributes.setElementAt(af,i); |
| |
| } |
| } |
| |
| // attribute "des" not found |
| if (i == preconditionAttributes.size()) |
| { |
| // create attribute for the status-type supplied |
| // with the values strength-tag and direction-tag |
| NameValue nv = |
| new NameValue("des", "qos " + strength + " " + status + " " + direction); |
| |
| AttributeField newAF = new AttributeField(); |
| newAF.setAttribute(nv); |
| preconditionAttributes.add(newAF); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| /** |
| * <p>Set attribute line for confirmation precondition request, given |
| * a string value encoded like the "conf" attribute value</p> |
| * |
| * @param precondConfValue - a string with the value for a "conf" attribute |
| * @throws SdpException |
| */ |
| public void setPreconditionConfirmStatus(String precondConfValue) |
| throws SdpException |
| { |
| if (precondConfValue == null || precondConfValue.length()==0) |
| throw new SdpException("The Precondition \"conf\" attribute value is null"); |
| else if (preconditionAttributes == null) |
| throw new SdpException("The Precondition Attributes is null"); |
| else |
| { |
| /* split the "conf" attribute value into words |
| * attributes[0] = "qos" |
| * attributes[1] = status-type (e2e/local/remote) |
| * attributes[2] = direction-tag (none/send/recv/sendrecv) |
| */ |
| try |
| { |
| String[] attributes = precondConfValue.split(" "); |
| |
| setPreconditionConfirmStatus( |
| attributes[1], // status-type |
| attributes[2] // direction-tag |
| ); |
| } |
| catch (ArrayIndexOutOfBoundsException ex) |
| { |
| throw new SdpException |
| ("Error spliting the \"conf\" attribute into words", ex); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| /** |
| * <p>IETF RFC3312</p> |
| * <p>"The confirmation status attribute carries threshold conditions |
| * for a media stream. When the status of network resources reach |
| * these conditions, the peer UA will send an update of the |
| * session description".</p> |
| * |
| * <p>- eg: a=conf:qos remote sendrecv</p> |
| * |
| * @param status - (e2e, local, remote) |
| * @param direction - (none, send, recv, sendrecv) |
| * @throws SdpException -- if param are null |
| */ |
| public void setPreconditionConfirmStatus(String status, String direction) |
| throws SdpException |
| { |
| if (status == null || direction.length()==0) |
| throw new SdpException("The status-type is null"); |
| if (direction == null || direction.length()==0) |
| throw new SdpException("The direction-tag is null"); |
| |
| if (preconditionAttributes == null) |
| throw new SdpException("Precondition Attributes is null"); |
| |
| int i = 0; |
| // search for attributes "conf" |
| for (i = 0; i < preconditionAttributes.size(); i++) |
| { |
| AttributeField af = |
| (AttributeField) this.preconditionAttributes.elementAt(i); |
| |
| |
| //System.out.println("--> PreconditionField -> (i="+i+") > attribute field: " + af.toString()); |
| |
| |
| // go to next attribute if this is not "conf" |
| if (!af.getAttribute().getName().equals("conf")) |
| continue; |
| |
| // if it is "conf" attribute, check the status-type |
| // if it matches, update the direction-tag |
| // with the value supplied |
| if (af.getValue().indexOf(status) != -1) |
| { |
| if (af.getValue().indexOf(direction) == -1) |
| { |
| // attribute exists with same status, directionTag updated |
| af.setValue("qos " + status + " " + direction); |
| preconditionAttributes.setElementAt(af,i); |
| } |
| // else, exit and do nothing (attribute already exists) |
| break; |
| } |
| } |
| |
| // attribute "conf" not found |
| if (i == preconditionAttributes.size()) |
| { |
| // create attribute for the status-type supplied |
| // with the values strength-tag and direction-tag |
| NameValue nv = |
| new NameValue("conf", "qos " + status + " " + direction); |
| |
| AttributeField newAF = new AttributeField(); |
| newAF.setAttribute(nv); |
| preconditionAttributes.add(newAF); |
| |
| |
| //System.out.println("--> PreconditionField -> new \"conf\" attribute created: " + newAF.toString() ); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| /** |
| * <p>Get the attribute fields with the name "curr" |
| * for current precondition.</p> |
| * <p>One attribute field per status-type. |
| * (eg: a=curr:qos local none)</p> |
| * |
| * @param status - (local, remote, e2e) |
| * @return a vector with the attribute field that match status-type |
| * (with only one element or null if none exists) |
| * @throws SdpParseException |
| */ |
| public Vector getPreconditionCurr(String status) |
| throws SdpException, SdpParseException |
| { |
| if (status == null) |
| throw new SdpException("The status-type is null"); |
| |
| if (preconditionAttributes == null) |
| return null; |
| else |
| { |
| Vector vCurr = new Vector(); |
| for (int i=0; i < preconditionAttributes.size(); i++) |
| { |
| AttributeField af = |
| (AttributeField) this.preconditionAttributes.elementAt(i); |
| |
| // go to next attribute if this is not "curr" |
| if (!af.getAttribute().getName().equals("curr")) |
| continue; |
| |
| // if it is "curr" attribute, check the status-type |
| // and add the attribute value to the vector if it |
| // matches the status desired |
| if (af.getValue().indexOf(status) != -1) |
| vCurr.addElement(af); |
| } |
| |
| // if none "curr" attribute found |
| if (vCurr.size() == 0) |
| return null; |
| else |
| return vCurr; |
| } |
| } |
| |
| |
| |
| |
| /** |
| * <p>Get the attribute fields with the name "des" |
| * for desired precondition</p> |
| * |
| * <p>There can be more than one current precondition line |
| * for a status-type (with different direction-tag values), |
| * specially if strength-tag is different</p> |
| * |
| * @param status - (local, remote, e2e) |
| * @return a vector with the attribute fields that match location-tag |
| * @throws SdpParseException |
| */ |
| public Vector getPreconditionDes(String status) |
| throws SdpException, SdpParseException |
| { |
| if (status == null) |
| throw new SdpException("The status-type is null"); |
| |
| if (preconditionAttributes == null) |
| return null; |
| else |
| { |
| Vector vCurr = new Vector(); |
| for (int i=0; i < preconditionAttributes.size(); i++) |
| { |
| AttributeField af = |
| (AttributeField) this.preconditionAttributes.elementAt(i); |
| |
| // go to next attribute if this is not "des" |
| if (!af.getAttribute().getName().equals("des")) |
| continue; |
| |
| // if it is "des" attribute, check the status-type |
| // and add the attribute value to the vector if it |
| // matches the status desired |
| if (af.getValue().indexOf(status) != -1) |
| vCurr.addElement(af); |
| } |
| |
| // if none "des" attribute found |
| if (vCurr.size() == 0) |
| return null; |
| else |
| return vCurr; |
| } |
| } |
| |
| |
| |
| /** |
| * <p>Get the attribute fields with the name "conf" |
| * for confirmation precondition.</p> |
| * |
| * <p>IETF RFC3312</p> |
| * <p>"The confirmation status attribute carries threshold conditions |
| * for a media stream. When the status of network resources reach |
| * these conditions, the peer UA will send an update of the |
| * session description".</p> |
| * |
| * <p>(eg: a=conf:qos remote sendrecv)</p> |
| * |
| * @return a vector with the "conf" attribute fields |
| * @throws SdpException |
| */ |
| public Vector getPreconditionConfirmStatus() throws SdpException |
| { |
| if (preconditionAttributes == null) |
| return null; // ignore or send SdpException? |
| else |
| { |
| Vector vCurr = new Vector(); |
| for (int i=0; i < preconditionAttributes.size(); i++) |
| { |
| AttributeField af = |
| (AttributeField) this.preconditionAttributes.elementAt(i); |
| |
| // go to next attribute if this is not "conf" |
| if (!af.getAttribute().getName().equals("conf")) |
| continue; |
| else |
| // add the attribute value to the vector |
| vCurr.addElement(af); |
| } |
| |
| // if none "conf" attribute found |
| if (vCurr.size() == 0) |
| return null; |
| else |
| return vCurr; |
| } |
| } |
| |
| |
| |
| /* strength-tag */ |
| public static final int STRENGTH_UNKNOWN = 0; |
| public static final int STRENGTH_FAILURE = 1; |
| public static final int STRENGTH_NONE = 2; |
| public static final int STRENGTH_OPTIONAL = 3; |
| public static final int STRENGTH_MANDATORY = 4; |
| public static final String[] STRENGTH = { "unknown", |
| "failure", |
| "none", |
| "optional", |
| "mandatory" |
| }; |
| /* direction-tag */ |
| public static final int DIRECTION_NONE = 0; |
| public static final int DIRECTION_SEND = 1; |
| public static final int DIRECTION_RECV = 2; |
| public static final int DIRECTION_SENDRECV = 3; |
| public static final String[] DIRECTION = { "none", |
| "send", |
| "recv", |
| "sendrecv" |
| }; |
| |
| /* status-tag */ |
| public static final int STATUS_E2E = 0; |
| public static final int STATUS_LOCAL = 1; |
| public static final int STATUS_REMOTE = 2; |
| public static final String[] STATUS = { "e2e", |
| "local", |
| "remote" |
| }; |
| |
| /* precondition type */ |
| public static final int PRECONDITION_QOS = 0; |
| public static final String[] PRECONDITION = { "qos" |
| }; |
| |
| |
| |
| |
| |
| |
| } |