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.net.InetAddress;
11 import java.nio.ByteBuffer;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.apache.commons.lang3.BooleanUtils;
15 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
16 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
17 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
18 import org.opendaylight.lispflowmapping.lisp.util.NumberUtil;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
29 * This class deals with deserializing map register from udp to the java object.
31 public final class MapRegisterSerializer {
33 private static final MapRegisterSerializer INSTANCE = new MapRegisterSerializer();
35 // Private constructor prevents instantiation from other classes
36 private MapRegisterSerializer() {
39 public static MapRegisterSerializer getInstance() {
43 public ByteBuffer serialize(MapRegister mapRegister) {
44 int size = Length.HEADER_SIZE;
45 if (mapRegister.getAuthenticationData() != null) {
46 size += mapRegister.getAuthenticationData().length;
48 if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
49 size += Length.XTRID_SIZE + Length.SITEID_SIZE;
51 for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
52 size += MappingRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord.getMappingRecord());
55 ByteBuffer registerBuffer = ByteBuffer.allocate(size);
56 registerBuffer.put((byte) ((byte) (MessageType.MapRegister.getIntValue() << 4)
57 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY)
58 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isXtrSiteIdPresent()), Flags.XTRSITEID)));
59 registerBuffer.position(registerBuffer.position() + Length.RES);
60 registerBuffer.put((byte)
61 (ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isMergeEnabled()), Flags.MERGE_ENABLED)
62 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_NOTIFY)));
63 registerBuffer.put((byte) mapRegister.getMappingRecordItem().size());
64 registerBuffer.putLong(NumberUtil.asLong(mapRegister.getNonce()));
65 registerBuffer.putShort(NumberUtil.asShort(mapRegister.getKeyId()));
67 if (mapRegister.getAuthenticationData() != null) {
68 registerBuffer.putShort((short) mapRegister.getAuthenticationData().length);
69 registerBuffer.put(mapRegister.getAuthenticationData());
71 registerBuffer.putShort((short) 0);
73 for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
74 MappingRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord.getMappingRecord());
77 if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
78 registerBuffer.put(mapRegister.getXtrId().getValue());
79 registerBuffer.put(mapRegister.getSiteId().getValue());
81 registerBuffer.clear();
82 return registerBuffer;
85 @SuppressWarnings("checkstyle:IllegalCatch")
86 public MapRegister deserialize(ByteBuffer registerBuffer, InetAddress sourceRloc) {
88 final byte typeAndFlags = registerBuffer.get();
89 final int type = typeAndFlags >> 4;
90 if (MessageType.forValue(type) != MessageType.MapRegister) {
91 throw new LispSerializationException("Expected Map-Register packet (type 3), but was type " + type);
94 MapRegisterBuilder builder = new MapRegisterBuilder();
95 builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
97 boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
98 builder.setProxyMapReply(ByteUtil.extractBit(typeAndFlags, Flags.PROXY));
99 builder.setXtrSiteIdPresent(xtrSiteIdPresent);
101 registerBuffer.position(registerBuffer.position() + Length.RES);
102 byte mergeAndMapReply = registerBuffer.get();
103 builder.setWantMapNotify(ByteUtil.extractBit(mergeAndMapReply, Flags.WANT_MAP_NOTIFY));
104 builder.setMergeEnabled(ByteUtil.extractBit(mergeAndMapReply, Flags.MERGE_ENABLED));
105 byte recordCount = (byte) ByteUtil.getUnsignedByte(registerBuffer);
106 builder.setNonce(registerBuffer.getLong());
107 builder.setKeyId(registerBuffer.getShort());
108 short authenticationLength = registerBuffer.getShort();
109 byte[] authenticationData = new byte[authenticationLength];
110 registerBuffer.get(authenticationData);
111 builder.setAuthenticationData(authenticationData);
113 if (xtrSiteIdPresent) {
114 List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
115 for (int i = 0; i < recordCount; i++) {
116 mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(registerBuffer));
118 byte[] xtrIdBuf = new byte[Length.XTRID_SIZE];
119 registerBuffer.get(xtrIdBuf);
120 XtrId xtrId = new XtrId(xtrIdBuf);
121 byte[] siteIdBuf = new byte[Length.SITEID_SIZE];
122 registerBuffer.get(siteIdBuf);
123 SiteId siteId = new SiteId(siteIdBuf);
124 builder.setXtrId(xtrId);
125 builder.setSiteId(siteId);
126 for (MappingRecordBuilder mrb : mrbs) {
128 mrb.setSiteId(siteId);
129 mrb.setSourceRloc(LispAddressUtil.addressBinaryFromInet(sourceRloc));
130 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
131 mrb.build()).build());
134 for (int i = 0; i < recordCount; i++) {
135 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
136 MappingRecordSerializer.getInstance().deserialize(registerBuffer)).build());
140 registerBuffer.limit(registerBuffer.position());
141 byte[] mapRegisterBytes = new byte[registerBuffer.position()];
142 registerBuffer.position(0);
143 registerBuffer.get(mapRegisterBytes);
144 return builder.build();
145 } catch (RuntimeException re) {
146 throw new LispSerializationException("Couldn't deserialize Map-Register (len="
147 + registerBuffer.capacity() + ")", re);
151 private interface Flags {
153 byte XTRSITEID = 0x02;
154 byte MERGE_ENABLED = 0x04;
155 byte WANT_MAP_NOTIFY = 0x01;
158 public interface Length {
159 int HEADER_SIZE = 16;