2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.parser;
10 import java.util.Arrays;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
15 import org.opendaylight.protocol.framework.ProtocolMessageHeader;
16 import org.opendaylight.protocol.util.ByteArray;
17 import com.google.common.primitives.UnsignedBytes;
20 * Representation of BGP Message Header. Includes methods for parsing and serializing header.
21 * Length field represents the length of the message including the length of its header.
23 public class BGPMessageHeader implements ProtocolMessageHeader {
25 public static final Logger logger = LoggerFactory.getLogger(BGPMessageHeader.class);
28 * BGP message header fixed length (in bytes)
30 public static final int COMMON_HEADER_LENGTH = 19;
32 private static final int MARKER_SIZE = 16;
33 private static final int LENGTH_SIZE = 2;
34 private static final int TYPE_OFFSET = MARKER_SIZE + LENGTH_SIZE;
38 private boolean parsed = false;
41 * Creates message header.
43 public BGPMessageHeader() {
48 * Creates message header with given attributes.
52 public BGPMessageHeader(final int type, final int length) {
58 * Creates a BGP Message Header from given byte array.
60 * @param bytes byte array to be parsed
61 * @return BGP Message Header
63 public BGPMessageHeader fromBytes(final byte[] bytes) {
65 throw new IllegalArgumentException("Array of bytes is mandatory");
66 //FIXME: how to send Notification message from this point?
67 // final byte[] ones = new byte[MARKER_SIZE];
68 // Arrays.fill(ones, (byte)0xff);
70 // if (Arrays.equals(bytes, ones))
71 // throw new BGPDocumentedException("Marker not set to ones.", BGPError.CONNECTION_NOT_SYNC);
73 logger.trace("Attempt to parse message header: {}", ByteArray.bytesToHexString(bytes));
75 if (bytes.length < COMMON_HEADER_LENGTH)
76 throw new IllegalArgumentException("Too few bytes in passed array. Passed: " + bytes.length + ". Expected: >= " + COMMON_HEADER_LENGTH + ".");
78 this.length = ByteArray.bytesToInt(ByteArray.subByte(bytes, MARKER_SIZE, LENGTH_SIZE));
80 this.type = UnsignedBytes.toInt(bytes[TYPE_OFFSET]);
82 logger.trace("Message header was parsed. {}", this);
88 * Serializes this BGP Message header to byte array.
90 * @return byte array representation of this header
92 public byte[] toBytes() {
93 final byte[] retBytes = new byte[COMMON_HEADER_LENGTH];
95 Arrays.fill(retBytes, 0, MARKER_SIZE, (byte)0xff);
97 System.arraycopy(ByteArray.intToBytes(this.length), Integer.SIZE / Byte.SIZE - LENGTH_SIZE, retBytes, MARKER_SIZE, LENGTH_SIZE);
99 retBytes[TYPE_OFFSET] = (byte) this.type;
105 * Returns length presented in Length field of this header.
107 * @return length of the BGP message
109 public int getLength() {
114 * Returns type presented in Type field of this header.
116 * @return type of the BGP message
118 public int getType() {
123 * Return the state of the parsing of this header.
125 * @return the parsed true if the header was parsed false if the header was not parsed
127 public boolean isParsed() {
132 * Marks parsing as not finished. There is no need for other classes to mark parsing as done, therefore calling this
133 * method will set parsing to unfinished.
135 public void setParsed() {