Activate code generation
[bgpcep.git] / bgp / parser-api / src / main / java / org / opendaylight / protocol / bgp / parser / BGPMessageHeader.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.parser;
9
10 import java.util.Arrays;
11
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import org.opendaylight.protocol.framework.ProtocolMessageHeader;
16 import org.opendaylight.protocol.util.ByteArray;
17 import com.google.common.primitives.UnsignedBytes;
18
19 /**
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.
22  */
23 public class BGPMessageHeader implements ProtocolMessageHeader {
24
25         public static final Logger logger = LoggerFactory.getLogger(BGPMessageHeader.class);
26
27         /**
28          * BGP message header fixed length (in bytes)
29          */
30         public static final int COMMON_HEADER_LENGTH = 19;
31
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;
35
36         private int type;
37         private int length;
38         private boolean parsed = false;
39
40         /**
41          * Creates message header.
42          */
43         public BGPMessageHeader() {
44
45         }
46
47         /**
48          * Creates message header with given attributes.
49          * @param type int
50          * @param length int
51          */
52         public BGPMessageHeader(final int type, final int length) {
53                 this.type = type;
54                 this.length = length;
55         }
56
57         /**
58          * Creates a BGP Message Header from given byte array.
59          *
60          * @param bytes byte array to be parsed
61          * @return BGP Message Header
62          */
63         public BGPMessageHeader fromBytes(final byte[] bytes) {
64                 if (bytes == null)
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);
69                 //
70                 //              if (Arrays.equals(bytes, ones))
71                 //                      throw new BGPDocumentedException("Marker not set to ones.", BGPError.CONNECTION_NOT_SYNC);
72
73                 logger.trace("Attempt to parse message header: {}", ByteArray.bytesToHexString(bytes));
74
75                 if (bytes.length < COMMON_HEADER_LENGTH)
76                         throw new IllegalArgumentException("Too few bytes in passed array. Passed: " + bytes.length + ". Expected: >= " + COMMON_HEADER_LENGTH + ".");
77
78                 this.length = ByteArray.bytesToInt(ByteArray.subByte(bytes, MARKER_SIZE, LENGTH_SIZE));
79
80                 this.type = UnsignedBytes.toInt(bytes[TYPE_OFFSET]);
81
82                 logger.trace("Message header was parsed. {}", this);
83                 this.parsed = true;
84                 return this;
85         }
86
87         /**
88          * Serializes this BGP Message header to byte array.
89          *
90          * @return byte array representation of this header
91          */
92         public byte[] toBytes() {
93                 final byte[] retBytes = new byte[COMMON_HEADER_LENGTH];
94
95                 Arrays.fill(retBytes, 0, MARKER_SIZE, (byte)0xff);
96
97                 System.arraycopy(ByteArray.intToBytes(this.length), Integer.SIZE / Byte.SIZE - LENGTH_SIZE, retBytes, MARKER_SIZE, LENGTH_SIZE);
98
99                 retBytes[TYPE_OFFSET] = (byte) this.type;
100
101                 return retBytes;
102         }
103
104         /**
105          * Returns length presented in Length field of this header.
106          *
107          * @return length of the BGP message
108          */
109         public int getLength() {
110                 return this.length;
111         }
112
113         /**
114          * Returns type presented in Type field of this header.
115          *
116          * @return type of the BGP message
117          */
118         public int getType() {
119                 return this.type;
120         }
121
122         /**
123          * Return the state of the parsing of this header.
124          *
125          * @return the parsed true if the header was parsed false if the header was not parsed
126          */
127         public boolean isParsed() {
128                 return this.parsed;
129         }
130
131         /**
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.
134          */
135         public void setParsed() {
136                 this.parsed = false;
137         }
138 }