/* | |
* Copyright 2015 Open Networking Laboratory | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.onosproject.pcepio.protocol.ver1; | |
import java.util.LinkedList; | |
import java.util.ListIterator; | |
import org.jboss.netty.buffer.ChannelBuffer; | |
import org.onosproject.pcepio.exceptions.PcepParseException; | |
import org.onosproject.pcepio.protocol.PcInitiatedLspRequest; | |
import org.onosproject.pcepio.protocol.PcepAttribute; | |
import org.onosproject.pcepio.protocol.PcepEndPointsObject; | |
import org.onosproject.pcepio.protocol.PcepEroObject; | |
import org.onosproject.pcepio.protocol.PcepInitiateMsg; | |
import org.onosproject.pcepio.protocol.PcepLspObject; | |
import org.onosproject.pcepio.protocol.PcepMessageReader; | |
import org.onosproject.pcepio.protocol.PcepMessageWriter; | |
import org.onosproject.pcepio.protocol.PcepSrpObject; | |
import org.onosproject.pcepio.protocol.PcepType; | |
import org.onosproject.pcepio.protocol.PcepVersion; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import com.google.common.base.MoreObjects; | |
class PcepInitiateMsgVer1 implements PcepInitiateMsg { | |
protected static final Logger log = LoggerFactory.getLogger(PcepInitiateMsgVer1.class); | |
// Ref : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03, section 5.1 | |
/* <PCInitiate Message> ::= <Common Header> | |
* <PCE-initiated-lsp-list> | |
* Where: | |
* <PCE-initiated-lsp-list> ::= <PCE-initiated-lsp-request>[<PCE-initiated-lsp-list>] | |
* <PCE-initiated-lsp-request> ::= (<PCE-initiated-lsp-instantiation>|<PCE-initiated-lsp-deletion>) | |
* <PCE-initiated-lsp-instantiation> ::= <SRP> | |
* <LSP> | |
* <END-POINTS> | |
* <ERO> | |
* [<attribute-list>] | |
* <PCE-initiated-lsp-deletion> ::= <SRP> | |
* <LSP> | |
*/ | |
static final byte PACKET_VERSION = 1; | |
/* considering LspDelete Request PcInitiate msg will contain | |
* common header | |
* srp object | |
* lsp object | |
* so min length for this can be | |
* PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+SrpObjectMinLen(12)+LspObjectMinLen(8) | |
*/ | |
public static final short PACKET_MINIMUM_LENGTH = 24; | |
public static final short MINIMUM_COMMON_HEADER_LENGTH = 4; | |
public static final PcepType MSG_TYPE = PcepType.INITIATE; | |
private LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList; | |
public static final PcepInitiateMsgVer1.Reader READER = new Reader(); | |
static class Reader implements PcepMessageReader<PcepInitiateMsg> { | |
LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList; | |
@Override | |
public PcepInitiateMsg readFrom(ChannelBuffer cb) throws PcepParseException { | |
if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { | |
return null; | |
} | |
llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>(); | |
byte version = cb.readByte(); | |
version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG); | |
if (version != PACKET_VERSION) { | |
throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), received=" + version); | |
} | |
byte type = cb.readByte(); | |
if (type != MSG_TYPE.getType()) { | |
throw new PcepParseException("Wrong type. Expected=PcepType.INITIATE(12), recived=" + type); | |
} | |
short length = cb.readShort(); | |
if (length < PACKET_MINIMUM_LENGTH) { | |
throw new PcepParseException("Wrong length. Initiate message length expected to be >= " | |
+ PACKET_MINIMUM_LENGTH + ", but received=" + length); | |
} | |
log.debug("reading PcInitiate message of length " + length); | |
// parse Start initiate/deletion list | |
if (!parsePcInitiatedLspRequestList(cb)) { | |
throw new PcepParseException("Parsing PCE-initiated-lsp-Request-list failed"); | |
} | |
return new PcepInitiateMsgVer1(llPcInitiatedLspRequestList); | |
} | |
/** | |
* To parse PcInitiatedLspRequestList from PcInitiate Message. | |
* | |
* @param cb of type channel buffer | |
* @return true if parsing PcInitiatedLspRequestList is success, false otherwise | |
* @throws PcepParseException while parsing from channel buffer | |
*/ | |
public boolean parsePcInitiatedLspRequestList(ChannelBuffer cb) throws PcepParseException { | |
boolean isDelLspRequest = false; | |
if (null == cb) { | |
throw new PcepParseException("Channel buffer is empty"); | |
} | |
while (0 < cb.readableBytes()) { | |
PcInitiatedLspRequest pceInitLspReq = new PcInitiatedLspRequestVer1(); | |
//store SRP object | |
PcepSrpObject srpObj; | |
srpObj = PcepSrpObjectVer1.read(cb); | |
pceInitLspReq.setSrpObject(srpObj); | |
isDelLspRequest = srpObj.getRFlag(); | |
//store LSP object | |
PcepLspObject lspObj; | |
lspObj = PcepLspObjectVer1.read(cb); | |
pceInitLspReq.setLspObject(lspObj); | |
/* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects | |
* so if R bit is not set then we should read for Ero and EndPoint objects also. | |
*/ | |
if (!isDelLspRequest) { | |
//store EndPoint object | |
PcepEndPointsObject endPointObj; | |
endPointObj = PcepEndPointsObjectVer1.read(cb); | |
pceInitLspReq.setEndPointsObject(endPointObj); | |
//store ERO object | |
PcepEroObject eroObj; | |
eroObj = PcepEroObjectVer1.read(cb); | |
pceInitLspReq.setEroObject(eroObj); | |
if (cb.readableBytes() > MINIMUM_COMMON_HEADER_LENGTH) { | |
pceInitLspReq.setPcepAttribute(PcepAttributeVer1.read(cb)); | |
} | |
} | |
llPcInitiatedLspRequestList.add(pceInitLspReq); | |
} | |
return true; | |
} | |
} | |
/** | |
* Constructor to initialize PcInitiatedLspRequest. | |
* | |
* @param llPcInitiatedLspRequestList list of PcInitiatedLspRequest | |
*/ | |
PcepInitiateMsgVer1(LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList) { | |
if (llPcInitiatedLspRequestList == null) { | |
throw new NullPointerException("PcInitiatedLspRequestList cannot be null."); | |
} | |
this.llPcInitiatedLspRequestList = llPcInitiatedLspRequestList; | |
} | |
/** | |
* Builder class for PCEP initiate message. | |
*/ | |
static class Builder implements PcepInitiateMsg.Builder { | |
// Pcep initiate message fields | |
LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList; | |
@Override | |
public PcepVersion getVersion() { | |
return PcepVersion.PCEP_1; | |
} | |
@Override | |
public PcepType getType() { | |
return PcepType.INITIATE; | |
} | |
@Override | |
public PcepInitiateMsg build() { | |
return new PcepInitiateMsgVer1(this.llPcInitiatedLspRequestList); | |
} | |
@Override | |
public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() { | |
return this.llPcInitiatedLspRequestList; | |
} | |
@Override | |
public Builder setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) { | |
this.llPcInitiatedLspRequestList = ll; | |
return this; | |
} | |
} | |
@Override | |
public void writeTo(ChannelBuffer cb) throws PcepParseException { | |
WRITER.write(cb, this); | |
} | |
static final Writer WRITER = new Writer(); | |
static class Writer implements PcepMessageWriter<PcepInitiateMsgVer1> { | |
@Override | |
public void write(ChannelBuffer cb, PcepInitiateMsgVer1 message) throws PcepParseException { | |
boolean isDelLspRequest = false; | |
int startIndex = cb.writerIndex(); | |
// first 3 bits set to version | |
cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG)); | |
// message type 0xC | |
cb.writeByte(MSG_TYPE.getType()); | |
// length is length of variable message, will be updated at the end | |
// Store the position of message | |
// length in buffer | |
int msgLenIndex = cb.writerIndex(); | |
cb.writeShort(0); | |
ListIterator<PcInitiatedLspRequest> listIterator = message.llPcInitiatedLspRequestList.listIterator(); | |
while (listIterator.hasNext()) { | |
PcInitiatedLspRequest listReq = listIterator.next(); | |
//Srp Object is mandatory | |
PcepSrpObject srpObj = listReq.getSrpObject(); | |
if (srpObj instanceof PcepSrpObject) { | |
isDelLspRequest = srpObj.getRFlag(); | |
srpObj.write(cb); | |
} else { | |
throw new PcepParseException("SRP Object is mandatory for PcInitiate message."); | |
} | |
//LSP Object is mandatory | |
PcepLspObject lspObj = listReq.getLspObject(); | |
if (lspObj instanceof PcepLspObject) { | |
lspObj.write(cb); | |
} else { | |
throw new PcepParseException("LSP Object is mandatory for PcInitiate message."); | |
} | |
/* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects | |
* so if R bit is not set then we should read for Ero and EndPoint objects also. | |
*/ | |
if (!isDelLspRequest) { | |
//EndPoints object is mandatory | |
PcepEndPointsObject endPointObj = listReq.getEndPointsObject(); | |
if (endPointObj instanceof PcepEndPointsObject) { | |
endPointObj.write(cb); | |
} else { | |
throw new PcepParseException("End points Object is mandatory for PcInitiate message."); | |
} | |
//Ero object is mandatory | |
PcepEroObject eroObj = listReq.getEroObject(); | |
if (eroObj instanceof PcepEroObject) { | |
eroObj.write(cb); | |
} else { | |
throw new PcepParseException("ERO Object is mandatory for PcInitiate message."); | |
} | |
//PcepAttribute is optional | |
PcepAttribute pcepAttribute = listReq.getPcepAttribute(); | |
if (pcepAttribute instanceof PcepAttribute) { | |
pcepAttribute.write(cb); | |
} | |
} | |
} | |
// PCInitiate message length field | |
int length = cb.writerIndex() - startIndex; | |
cb.setShort(msgLenIndex, (short) length); | |
} | |
} | |
@Override | |
public PcepVersion getVersion() { | |
return PcepVersion.PCEP_1; | |
} | |
@Override | |
public PcepType getType() { | |
return MSG_TYPE; | |
} | |
@Override | |
public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() { | |
return this.llPcInitiatedLspRequestList; | |
} | |
@Override | |
public void setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) { | |
this.llPcInitiatedLspRequestList = ll; | |
} | |
@Override | |
public String toString() { | |
return MoreObjects.toStringHelper(getClass()).add("PcInitiaitedLspRequestList", llPcInitiatedLspRequestList) | |
.toString(); | |
} | |
} |