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.impl;
10 import java.util.Arrays;
11 import java.util.List;
13 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
14 import org.opendaylight.protocol.bgp.parser.BGPError;
15 import org.opendaylight.protocol.bgp.parser.BGPMessageFactory;
16 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
17 import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
18 import org.opendaylight.protocol.framework.DeserializerException;
19 import org.opendaylight.protocol.framework.DocumentedException;
20 import org.opendaylight.protocol.util.ByteArray;
21 import org.opendaylight.yangtools.yang.binding.Notification;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 import com.google.common.collect.Lists;
26 import com.google.common.primitives.UnsignedBytes;
28 abstract class AbstractMessageRegistry implements BGPMessageFactory, MessageRegistry {
29 private final static Logger logger = LoggerFactory.getLogger(AbstractMessageRegistry.class);
31 protected abstract Notification parseBody(final int type, final byte[] body, final int messageLength) throws BGPDocumentedException;
32 protected abstract byte[] serializeMessageImpl(final Notification message);
35 public final Notification parseMessage(final byte[] bytes) throws BGPDocumentedException, DeserializerException {
37 throw new IllegalArgumentException("Array of bytes is mandatory.");
39 if (bytes.length < MessageUtil.COMMON_HEADER_LENGTH) {
40 throw new IllegalArgumentException("Too few bytes in passed array. Passed: " + bytes.length + ". Expected: >= "
41 + MessageUtil.COMMON_HEADER_LENGTH + ".");
44 * byte array starts with message length
46 // final byte[] ones = new byte[MARKER_LENGTH];
47 // Arrays.fill(ones, (byte)0xff);
48 // if (Arrays.equals(bytes, ones))
49 // throw new BGPDocumentedException("Marker not set to ones.", BGPError.CONNECTION_NOT_SYNC);
50 final byte[] bs = ByteArray.cutBytes(bytes, MessageUtil.MARKER_LENGTH);
51 final int messageLength = ByteArray.bytesToInt(ByteArray.subByte(bs, 0, MessageUtil.LENGTH_FIELD_LENGTH));
52 final int messageType = UnsignedBytes.toInt(bs[MessageUtil.LENGTH_FIELD_LENGTH]);
54 final byte[] msgBody = ByteArray.cutBytes(bs, MessageUtil.LENGTH_FIELD_LENGTH + MessageUtil.TYPE_FIELD_LENGTH);
56 if (messageLength < MessageUtil.COMMON_HEADER_LENGTH) {
57 throw BGPDocumentedException.badMessageLength("Message length field not within valid range.", messageLength);
59 if (msgBody.length != messageLength - MessageUtil.COMMON_HEADER_LENGTH) {
60 throw new DeserializerException("Size doesn't match size specified in header. Passed: " + msgBody.length + "; Expected: "
61 + (messageLength - MessageUtil.COMMON_HEADER_LENGTH) + ". ");
64 logger.debug("Attempt to parse message from bytes: {}", ByteArray.bytesToHexString(msgBody));
66 final Notification msg = parseBody(messageType, msgBody, messageLength);
68 throw new BGPDocumentedException("Unhandled message type " + messageType, BGPError.BAD_MSG_TYPE, new byte[] { bs[MessageUtil.LENGTH_FIELD_LENGTH] });
75 public final byte[] serializeMessage(final Notification message) {
76 if (message == null) {
77 throw new IllegalArgumentException("BGPMessage is mandatory.");
80 logger.trace("Serializing {}", message);
82 final byte[] ret = serializeMessageImpl(message);
84 throw new IllegalArgumentException("Unknown instance of BGPMessage. Passed " + message.getClass());
87 logger.trace("Serialized BGP message {}.", Arrays.toString(ret));
93 * @see org.opendaylight.protocol.bgp.parser.BGPMessageParser#parse(byte[])
96 public final List<Notification> parse(final byte[] bytes) throws DeserializerException, DocumentedException {
97 return Lists.newArrayList(parseMessage(bytes));
101 public final byte[] put(final Notification msg) {
102 return serializeMessage(msg);