54b92d3e9fe2d4f13acb3e65292709ba5ba36d43
[bgpcep.git] / bgp / parser-impl / src / main / java / org / opendaylight / protocol / bgp / parser / impl / message / BGPNotificationMessageParser.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.impl.message;
9
10 import java.util.Arrays;
11
12 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
13 import org.opendaylight.protocol.bgp.parser.BGPError;
14 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
15 import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
16 import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
17 import org.opendaylight.protocol.util.ByteArray;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.Notify;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.NotifyBuilder;
20 import org.opendaylight.yangtools.yang.binding.Notification;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import com.google.common.primitives.UnsignedBytes;
25
26 /**
27  * Parser for BGPNotification message.
28  */
29 public final class BGPNotificationMessageParser implements MessageParser, MessageSerializer {
30         public static final int TYPE = 3;
31
32         private static final Logger logger = LoggerFactory.getLogger(BGPNotificationMessageParser.class);
33
34         private static final int ERROR_SIZE = 2;
35
36         /**
37          * Serializes BGP Notification message.
38          * 
39          * @param msg to be serialized
40          * @return BGP Notification message converted to byte array
41          */
42         @Override
43         public byte[] serializeMessage(final Notification msg) {
44                 if (msg == null) {
45                         throw new IllegalArgumentException("BGP Notification message cannot be null");
46                 }
47
48                 final Notify ntf = (Notify) msg;
49                 logger.trace("Started serializing Notification message: {}", ntf);
50
51                 final byte[] msgBody = (ntf.getData() == null) ? new byte[ERROR_SIZE] : new byte[ERROR_SIZE + ntf.getData().length];
52
53                 msgBody[0] = ByteArray.intToBytes(ntf.getErrorCode())[Integer.SIZE / Byte.SIZE - 1];
54
55                 msgBody[1] = ByteArray.intToBytes(ntf.getErrorSubcode())[Integer.SIZE / Byte.SIZE - 1];
56
57                 if (ntf.getData() != null) {
58                         System.arraycopy(ntf.getData(), 0, msgBody, ERROR_SIZE, ntf.getData().length);
59                 }
60
61                 final byte[] ret = MessageUtil.formatMessage(TYPE, msgBody);
62                 logger.trace("Notification message serialized to: {}", Arrays.toString(ret));
63                 return ret;
64         }
65
66         /**
67          * Parses BGP Notification message to bytes.
68          * 
69          * @param body byte array to be parsed
70          * @return BGPNotification message
71          * @throws BGPDocumentedException
72          */
73         @Override
74         public Notify parseMessageBody(final byte[] body, final int messageLength) throws BGPDocumentedException {
75                 if (body == null) {
76                         throw new IllegalArgumentException("Byte array cannot be null.");
77                 }
78                 logger.trace("Started parsing of notification message: {}", Arrays.toString(body));
79
80                 if (body.length < ERROR_SIZE) {
81                         throw BGPDocumentedException.badMessageLength("Notification message too small.", messageLength);
82                 }
83                 final int errorCode = UnsignedBytes.toInt(body[0]);
84                 final int errorSubcode = UnsignedBytes.toInt(body[1]);
85
86                 byte[] data = null;
87                 if (body.length > ERROR_SIZE) {
88                         data = ByteArray.subByte(body, ERROR_SIZE, body.length - ERROR_SIZE);
89                 }
90                 logger.trace("Notification message was parsed: err = {}, data = {}.", BGPError.forValue(errorCode, errorSubcode),
91                                 Arrays.toString(data));
92                 final NotifyBuilder builder = new NotifyBuilder().setErrorCode((short) errorCode).setErrorSubcode((short) errorSubcode);
93                 if (data != null) {
94                         builder.setData(data);
95                 }
96                 return builder.build();
97         }
98 }