2 * Copyright (c) 2014 Contextream, 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.lispflowmapping.lisp.serializer;
10 import java.nio.ByteBuffer;
11 import java.util.ArrayList;
13 import org.apache.commons.lang3.BooleanUtils;
14 import org.opendaylight.lispflowmapping.lisp.serializer.address.LispAddressSerializer;
15 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
16 import org.opendaylight.lispflowmapping.lisp.type.LispMessageEnum;
17 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
18 import org.opendaylight.lispflowmapping.lisp.util.LispAFIConvertor;
19 import org.opendaylight.lispflowmapping.lisp.util.NumberUtil;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidrecords.EidRecord;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidtolocatorrecords.EidToLocatorRecordBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRloc;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRlocBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEidBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequestBuilder;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * This class deals with deserializing map request from udp to the java object.
33 public class MapRequestSerializer {
35 private static final MapRequestSerializer INSTANCE = new MapRequestSerializer();
36 protected static final Logger LOG = LoggerFactory.getLogger(MapRequestSerializer.class);
38 // Private constructor prevents instantiation from other classes
39 private MapRequestSerializer() {
42 public static MapRequestSerializer getInstance() {
46 public ByteBuffer serialize(MapRequest mapRequest) {
47 int size = Length.HEADER_SIZE;
48 if (mapRequest.getSourceEid() != null && mapRequest.getSourceEid().getLispAddressContainer() != null) {
49 size += LispAddressSerializer.getInstance().getAddressSize(
50 LispAFIConvertor.toAFI(mapRequest.getSourceEid().getLispAddressContainer()));
54 if (mapRequest.getItrRloc() != null) {
55 for (ItrRloc address : mapRequest.getItrRloc()) {
56 size += LispAddressSerializer.getInstance().getAddressSize(LispAFIConvertor.toAFI(address.getLispAddressContainer()));
59 if (mapRequest.getEidRecord() != null) {
60 for (EidRecord record : mapRequest.getEidRecord()) {
61 size += 2 + LispAddressSerializer.getInstance().getAddressSize(LispAFIConvertor.toAFI(record.getLispAddressContainer()));
64 ByteBuffer requestBuffer = ByteBuffer.allocate(size);
65 requestBuffer.put((byte) ((byte) (LispMessageEnum.MapRequest.getValue() << 4)
66 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isAuthoritative()), Flags.AUTHORITATIVE)
67 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isMapDataPresent()), Flags.MAP_DATA_PRESENT)
68 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isProbe()), Flags.PROBE) | ByteUtil.boolToBit(
69 BooleanUtils.isTrue(mapRequest.isSmr()), Flags.SMR)));
70 requestBuffer.put((byte) (ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isPitr()), Flags.PITR) | ByteUtil.boolToBit(
71 BooleanUtils.isTrue(mapRequest.isSmrInvoked()), Flags.SMR_INVOKED)));
72 if (mapRequest.getItrRloc() != null) {
73 int IRC = mapRequest.getItrRloc().size();
77 requestBuffer.put((byte) (IRC));
79 requestBuffer.put((byte) 0);
82 if (mapRequest.getEidRecord() != null) {
83 requestBuffer.put((byte) mapRequest.getEidRecord().size());
85 requestBuffer.put((byte) 0);
88 requestBuffer.putLong(NumberUtil.asLong(mapRequest.getNonce()));
89 if (mapRequest.getSourceEid() != null && mapRequest.getSourceEid().getLispAddressContainer() != null) {
90 LispAddressSerializer.getInstance().serialize(requestBuffer,
91 LispAFIConvertor.toAFI(mapRequest.getSourceEid().getLispAddressContainer()));
93 requestBuffer.putShort((short) 0);
95 if (mapRequest.getItrRloc() != null) {
96 for (ItrRloc address : mapRequest.getItrRloc()) {
97 LispAddressSerializer.getInstance().serialize(requestBuffer, LispAFIConvertor.toAFI(address.getLispAddressContainer()));
100 if (mapRequest.getEidRecord() != null) {
101 for (EidRecord record : mapRequest.getEidRecord()) {
102 requestBuffer.put((byte) 0);
103 requestBuffer.put((byte) record.getMask().byteValue());
104 LispAddressSerializer.getInstance().serialize(requestBuffer, LispAFIConvertor.toAFI(record.getLispAddressContainer()));
107 if (mapRequest.getMapReply() != null) {
108 ByteBuffer replyBuffer = ByteBuffer.allocate(EidToLocatorRecordSerializer.getInstance().getSerializationSize(mapRequest.getMapReply()));
109 EidToLocatorRecordSerializer.getInstance().serialize(replyBuffer, mapRequest.getMapReply());
110 ByteBuffer combinedBuffer = ByteBuffer.allocate(requestBuffer.capacity() + replyBuffer.capacity());
111 combinedBuffer.put(requestBuffer.array());
112 combinedBuffer.put(replyBuffer.array());
113 return combinedBuffer;
115 return requestBuffer;
118 public MapRequest deserialize(ByteBuffer requestBuffer) {
120 MapRequestBuilder builder = new MapRequestBuilder();
122 byte typeAndFlags = requestBuffer.get();
123 builder.setAuthoritative(ByteUtil.extractBit(typeAndFlags, Flags.AUTHORITATIVE));
124 builder.setMapDataPresent(ByteUtil.extractBit(typeAndFlags, Flags.MAP_DATA_PRESENT));
125 builder.setProbe(ByteUtil.extractBit(typeAndFlags, Flags.PROBE));
126 builder.setSmr(ByteUtil.extractBit(typeAndFlags, Flags.SMR));
128 byte moreFlags = requestBuffer.get();
129 builder.setPitr(ByteUtil.extractBit(moreFlags, Flags.PITR));
130 builder.setSmrInvoked(ByteUtil.extractBit(moreFlags, Flags.SMR_INVOKED));
132 int itrCount = ByteUtil.getUnsignedByte(requestBuffer) + 1;
133 int recordCount = ByteUtil.getUnsignedByte(requestBuffer);
134 builder.setNonce(requestBuffer.getLong());
135 builder.setSourceEid(new SourceEidBuilder().setLispAddressContainer(
136 LispAFIConvertor.toContainer(LispAddressSerializer.getInstance().deserialize(requestBuffer)))
139 if (builder.getItrRloc() == null) {
140 builder.setItrRloc(new ArrayList<ItrRloc>());
142 for (int i = 0; i < itrCount; i++) {
143 builder.getItrRloc().add(
144 new ItrRlocBuilder().setLispAddressContainer(
145 LispAFIConvertor.toContainer(LispAddressSerializer.getInstance().deserialize(requestBuffer)))
149 if (builder.getEidRecord() == null) {
150 builder.setEidRecord(new ArrayList<EidRecord>());
152 for (int i = 0; i < recordCount; i++) {
153 builder.getEidRecord().add(EidRecordSerializer.getInstance().deserialize(requestBuffer));
155 if (builder.isMapDataPresent() && requestBuffer.hasRemaining()) {
157 builder.setMapReply(new org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.MapReplyBuilder(
158 new EidToLocatorRecordBuilder(EidToLocatorRecordSerializer.getInstance().deserialize(requestBuffer)).build()).build());
159 } catch (RuntimeException re) {
160 LOG.warn("couldn't deserialize map reply encapsulated in map request. {}", re.getMessage());
163 return builder.build();
164 } catch (RuntimeException re) {
165 throw new LispSerializationException("Couldn't deserialize Map-Request (len=" + requestBuffer.capacity() + ")", re);
169 public interface Flags {
170 byte AUTHORITATIVE = 0x08;
171 byte MAP_DATA_PRESENT = 0x04;
175 byte PITR = (byte) 0x80;
176 byte SMR_INVOKED = 0x40;
179 private interface Length {
180 int HEADER_SIZE = 12;