1
2
3
4
5
6
7
8 package org.opendaylight.lispflowmapping.lisp.serializer;
9
10 import java.nio.ByteBuffer;
11 import java.util.ArrayList;
12 import java.util.List;
13
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.NumberUtil;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
24
25
26
27
28 public final class MapNotifySerializer {
29
30 private static final MapNotifySerializer INSTANCE = new MapNotifySerializer();
31
32
33 private MapNotifySerializer() {
34 }
35
36 public static MapNotifySerializer getInstance() {
37 return INSTANCE;
38 }
39
40 public ByteBuffer serialize(MapNotify mapNotify) {
41 int size = Length.HEADER_SIZE;
42 if (mapNotify.getAuthenticationData() != null) {
43 size += mapNotify.getAuthenticationData().length;
44 }
45 if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
46 size += org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.XTRID_SIZE +
47 org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.SITEID_SIZE;
48 }
49 for (MappingRecordItem mappingRecord : mapNotify.getMappingRecordItem()) {
50 size += MappingRecordSerializer.getInstance().getSerializationSize(mappingRecord.getMappingRecord());
51 }
52
53 ByteBuffer replyBuffer = ByteBuffer.allocate(size);
54 replyBuffer.put((byte) (MessageType.MapNotify.getIntValue() << 4));
55 replyBuffer.position(replyBuffer.position() + Length.RES);
56 replyBuffer.put(ByteUtil.boolToBit(BooleanUtils.isTrue(mapNotify.isMergeEnabled()), Flags.MERGE_ENABLED));
57 if (mapNotify.getMappingRecordItem() != null) {
58 replyBuffer.put((byte) mapNotify.getMappingRecordItem().size());
59 } else {
60 replyBuffer.put((byte) 0);
61 }
62 replyBuffer.putLong(NumberUtil.asLong(mapNotify.getNonce()));
63 replyBuffer.putShort(NumberUtil.asShort(mapNotify.getKeyId()));
64 if (mapNotify.getAuthenticationData() != null) {
65 replyBuffer.putShort((short) mapNotify.getAuthenticationData().length);
66 replyBuffer.put(mapNotify.getAuthenticationData());
67 } else {
68 replyBuffer.putShort((short) 0);
69 }
70
71 if (mapNotify.getMappingRecordItem() != null) {
72 for (MappingRecordItem mappingRecord : mapNotify.getMappingRecordItem()) {
73 MappingRecordSerializer.getInstance().serialize(replyBuffer, mappingRecord.getMappingRecord());
74 }
75 }
76
77 if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
78 replyBuffer.put(mapNotify.getXtrId());
79 replyBuffer.put(mapNotify.getSiteId());
80 }
81 replyBuffer.clear();
82 return replyBuffer;
83 }
84
85 public MapNotify deserialize(ByteBuffer notifyBuffer) {
86 try {
87 MapNotifyBuilder builder = new MapNotifyBuilder();
88 builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
89
90 byte typeAndFlags = notifyBuffer.get();
91 boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
92 builder.setXtrSiteIdPresent(xtrSiteIdPresent);
93
94 notifyBuffer.position(notifyBuffer.position() + Length.RES);
95 builder.setMergeEnabled(ByteUtil.extractBit(notifyBuffer.get(), Flags.MERGE_ENABLED));
96
97 byte recordCount = (byte) ByteUtil.getUnsignedByte(notifyBuffer);
98 builder.setNonce(notifyBuffer.getLong());
99 builder.setKeyId(notifyBuffer.getShort());
100 short authenticationLength = notifyBuffer.getShort();
101 byte[] authenticationData = new byte[authenticationLength];
102 notifyBuffer.get(authenticationData);
103 builder.setAuthenticationData(authenticationData);
104
105 if (xtrSiteIdPresent) {
106 List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
107 for (int i = 0; i < recordCount; i++) {
108 mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(notifyBuffer));
109 }
110 byte[] xtrId = new byte[MapRegisterSerializer.Length.XTRID_SIZE];
111 notifyBuffer.get(xtrId);
112 byte[] siteId = new byte[MapRegisterSerializer.Length.SITEID_SIZE];
113 notifyBuffer.get(siteId);
114 builder.setXtrId(xtrId);
115 builder.setSiteId(siteId);
116 for (MappingRecordBuilder mrb : mrbs) {
117 mrb.setXtrId(xtrId);
118 mrb.setSiteId(siteId);
119 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
120 mrb.build()).build());
121 }
122 } else {
123 for (int i = 0; i < recordCount; i++) {
124 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
125 MappingRecordSerializer.getInstance().deserialize(notifyBuffer)).build());
126 }
127 }
128
129 notifyBuffer.limit(notifyBuffer.position());
130 return builder.build();
131 } catch (RuntimeException re) {
132 throw new LispSerializationException("Couldn't deserialize Map-Notify (len=" + notifyBuffer.capacity() + ")", re);
133 }
134 }
135
136 private interface Flags {
137 byte XTRSITEID = 0x08;
138 byte MERGE_ENABLED = 0x04;
139 }
140
141 private interface Length {
142 int HEADER_SIZE = 16;
143 int RES = 1;
144 }
145
146 }