All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.tid.pce.pcep.messages.PCEPUpdate Maven / Gradle / Ivy

The newest version!
package es.tid.pce.pcep.messages;

import java.util.LinkedList;

import es.tid.pce.pcep.PCEPProtocolViolationException;
import es.tid.pce.pcep.constructs.UpdateRequest;
import es.tid.pce.pcep.objects.ObjectParameters;
import es.tid.pce.pcep.objects.PCEPObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * PCUpd Message.
 * 
 * http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-mpls-te-00
 * 
 * 4.2. MPLS-TE specific descriptors for the PCUpd Message


   A Path Computation LSP Update Request message (also referred to as
   PCUpd message) is a PCEP message sent by a PCE to a PCC to update
   attributes of an LSP.  A PCUpd message can carry more than one LSP
   Update Request.  The Message-Type field of the PCEP common header for
   the PCUpd message is set to [TBD].

   The format of the PCUpd message is defined in
   [I-D.ietf-pce-stateful-pce] and included here for easy reference:

{@code
       ::= 
                          
   Where:

       ::= []

       ::= 
                           []

   Where:

      ::=[]

   For MPLS-TE LSPs, the endoding of path descriptor is defined as
   follows:

      ::=

   Where:
      ::=

   Where:

       ::= []
                           []
                           []

       ::= []}

   There is one mandatory object that MUST be included within each LSP
   Update Request in the PCUpd message: the LSP object (see
   [I-D.ietf-pce-stateful-pce]).  If the LSP object is missing, the
   receiving PCE MUST send a PCErr message with Error-type=6 (Mandatory
   Object missing) and Error-value=[TBD] (LSP object missing).

   The LSP Update Request MUST contain a path descriptor for the primary
   path, and MAY contain one or more path descriptors for backup paths.
   A path descriptor MUST contain an ERO object.  A path descriptor MAY
   further contain the BANDWIDTH, IRO, and METRIC objects.  The ERO,
   LSPA, BANDWIDTH, METRIC, and IRO objects are defined in [RFC5440].

   Each LSP Update Request results in a separate LSP setup operation at
   a PCC.  An LSP Update Request MUST contain all LSP parameters that a
   PCC wishes to set for the LSP.  A PCC MAY set missing parameters from
   locally configured defaults.  If the LSP specified the Update Request
   is already up, it will be re-signaled.  The PCC will use make-before-
   break whenever possible in the re-signaling operation.

   A PCC MUST respond with an LSP State Report to each LSP Update
   Request to indicate the resulting state of the LSP in the network.  A
   PCC MAY respond with multiple LSP State Reports to report LSP setup
   progress of a single LSP.

   If the rate of PCUpd messages sent to a PCC for the same target LSP
   exceeds the rate at which the PCC can signal LSPs into the network,
   the PCC MAY perform state compression and only re-signal the last
   modification in its queue.

   Note that a PCC MUST process all LSP Update Requests - for example,
   an LSP Update Request is sent when a PCE returns delegation or puts
   an LSP into non-operational state.  The protocol relies on TCP for
   message-level flow control.

   Note also that it's up to the PCE to handle inter-LSP dependencies;
   for example, if ordering of LSP set-ups is required, the PCE has to
   wait for an LSP State Report for a previous LSP before triggering the
   LSP setup of a next LSP.
   
 * @author Fernando Munoz del Nuevo
 * 
 *
 */


public class PCEPUpdate extends PCEPMessage{
	private static final Logger log = LoggerFactory.getLogger("PCEPParser");
	protected LinkedList updateRequestList;
	
	public PCEPUpdate(){
		this.setMessageType(PCEPMessageTypes.MESSAGE_UPDATE);
		updateRequestList = new LinkedList();
	}
	public PCEPUpdate(byte [] bytes)  throws PCEPProtocolViolationException{
		super(bytes);
		updateRequestList = new LinkedList();
		decode();
		
	}
	
	@Override
	public void encode() throws PCEPProtocolViolationException {
		// TODO Auto-generated method stub
		int len = 4;
		int index = 0;
        while(index < updateRequestList.size()){
			updateRequestList.get(index).encode();		
			len+=updateRequestList.get(index).getLength();
			index++;			
        }
		if (updateRequestList.size()==0){
			log.warn("There should be at least one update request in a PCEP update Request message");
			throw new PCEPProtocolViolationException();
		}
		this.setMessageLength(len);
		messageBytes=new byte[len];
		this.encodeHeader();
		int offset = 4;		//Header
		index=0;
		while(index < updateRequestList.size()){
			System.arraycopy(updateRequestList.get(index).getBytes(), 0, this.messageBytes, offset, updateRequestList.get(index).getLength());
			offset = offset + updateRequestList.get(index).getLength();
			index++;						
		}	
	}
	
	
	public void decode() throws PCEPProtocolViolationException{
		//Current implementation is strict, does not accept unknown objects 
		int offset=4;//We start after the object header
		boolean atLeastOne = false;
		
		UpdateRequest ur;
		
		//No LSP object. Malformed Update Request. PCERR mesage should be sent!
		if(PCEPObject.getObjectClass(this.getBytes(), offset)!=ObjectParameters.PCEP_OBJECT_CLASS_SRP)
		{
			throw new PCEPProtocolViolationException();
		}
		
		while (PCEPObject.getObjectClass(this.getBytes(), offset)==ObjectParameters.PCEP_OBJECT_CLASS_SRP){
			try
			{
				ur = new UpdateRequest(this.getBytes(),offset);
			}
			catch(PCEPProtocolViolationException e)
			{
				log.warn("Malformed UpdateRequest Construct");
				throw new PCEPProtocolViolationException();
			}
			offset=offset+ur.getLength();
			updateRequestList.add(ur);
			atLeastOne = true;
		}
		
		if (!atLeastOne)
		{
			log.warn("Malformed Report Message. There must be at least one update-list object. Exception will be throwed");
			throw new PCEPProtocolViolationException();
		}
	}

	public LinkedList getUpdateRequestList() {
		return updateRequestList;
	}

	public void setUpdateRequestList(LinkedList updateRequestList) {
		this.updateRequestList = updateRequestList;
	}
	
	public void addStateReport(UpdateRequest upRequest)
	{
		updateRequestList.add(upRequest);
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime
				* result
				+ ((updateRequestList == null) ? 0 : updateRequestList
						.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		PCEPUpdate other = (PCEPUpdate) obj;
		if (updateRequestList == null) {
			if (other.updateRequestList != null)
				return false;
		} else if (!updateRequestList.equals(other.updateRequestList))
			return false;
		return true;
	}
	
	public String toString(){
		StringBuffer sb=new StringBuffer(updateRequestList.size()*100);
		sb.append("UPDATE MESSAGE: ");
		for (int i=0;i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy