7d5de297eb81be45192c1af65964fc2abdb5b409
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / serializer / MapRegisterSerializer.java
1 package org.opendaylight.lispflowmapping.implementation.serializer;
2
3 import java.nio.ByteBuffer;
4 import java.util.ArrayList;
5
6 import org.apache.commons.lang3.BooleanUtils;
7 import org.opendaylight.lispflowmapping.implementation.lisp.exception.LispSerializationException;
8 import org.opendaylight.lispflowmapping.implementation.util.ByteUtil;
9 import org.opendaylight.lispflowmapping.implementation.util.NumberUtil;
10 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister;
11 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord;
12 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.mapregisternotification.MapRegisterBuilder;
13
14 /**
15  * This class deals with deserializing map register from udp to the java object.
16  */
17 public class MapRegisterSerializer {
18
19     private static final MapRegisterSerializer INSTANCE = new MapRegisterSerializer();
20
21     // Private constructor prevents instantiation from other classes
22     private MapRegisterSerializer() {
23     }
24
25     public static MapRegisterSerializer getInstance() {
26         return INSTANCE;
27     }
28
29     public ByteBuffer serialize(MapRegister mapRegister) {
30         int size = Length.HEADER_SIZE;
31         if (mapRegister.getAuthenticationData() != null) {
32             size += mapRegister.getAuthenticationData().length;
33         }
34         for (EidToLocatorRecord eidToLocatorRecord : mapRegister.getEidToLocatorRecord()) {
35             size += EidToLocatorRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord);
36         }
37
38         ByteBuffer registerBuffer = ByteBuffer.allocate(size);
39         registerBuffer.put((byte) ((byte) (LispMessageEnum.MapRegister.getValue() << 4) | ByteUtil.boolToBit(
40                 BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY)));
41         registerBuffer.position(registerBuffer.position() + Length.RES);
42         registerBuffer.put(ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_REPLY));
43         registerBuffer.put((byte) mapRegister.getEidToLocatorRecord().size());
44         registerBuffer.putLong(NumberUtil.asLong(mapRegister.getNonce()));
45         registerBuffer.putShort(NumberUtil.asShort(mapRegister.getKeyId()));
46
47         if (mapRegister.getAuthenticationData() != null) {
48             registerBuffer.putShort((short) mapRegister.getAuthenticationData().length);
49             registerBuffer.put(mapRegister.getAuthenticationData());
50         } else {
51             registerBuffer.putShort((short) 0);
52         }
53         for (EidToLocatorRecord eidToLocatorRecord : mapRegister.getEidToLocatorRecord()) {
54             EidToLocatorRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord);
55         }
56         registerBuffer.clear();
57         return registerBuffer;
58     }
59
60     public MapRegister deserialize(ByteBuffer registerBuffer) {
61         try {
62             MapRegisterBuilder builder = new MapRegisterBuilder();
63             builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
64
65             builder.setProxyMapReply(ByteUtil.extractBit(registerBuffer.get(), Flags.PROXY));
66
67             registerBuffer.position(registerBuffer.position() + Length.RES);
68             builder.setWantMapNotify(ByteUtil.extractBit(registerBuffer.get(), Flags.WANT_MAP_REPLY));
69             byte recordCount = (byte) ByteUtil.getUnsignedByte(registerBuffer);
70             builder.setNonce(registerBuffer.getLong());
71             builder.setKeyId(registerBuffer.getShort());
72             short authenticationLength = registerBuffer.getShort();
73             byte[] authenticationData = new byte[authenticationLength];
74             registerBuffer.get(authenticationData);
75             builder.setAuthenticationData(authenticationData);
76
77             for (int i = 0; i < recordCount; i++) {
78                 builder.getEidToLocatorRecord().add(EidToLocatorRecordSerializer.getInstance().deserialize(registerBuffer));
79             }
80             registerBuffer.limit(registerBuffer.position());
81             byte[] mapRegisterBytes = new byte[registerBuffer.position()];
82             registerBuffer.position(0);
83             registerBuffer.get(mapRegisterBytes);
84             return builder.build();
85         } catch (RuntimeException re) {
86             throw new LispSerializationException("Couldn't deserialize Map-Register (len=" + registerBuffer.capacity() + ")", re);
87         }
88
89     }
90
91     private interface Flags {
92         byte PROXY = 0x08;
93         byte WANT_MAP_REPLY = 0x01;
94     }
95
96     private interface Length {
97         int HEADER_SIZE = 16;
98         int RES = 1;
99     }
100 }