Reorganize mappingservice.implementation
[lispflowmapping.git] / mappingservice / yangmodel / src / main / java / org / opendaylight / lispflowmapping / lisp / serializer / MapRegisterSerializer.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.lispflowmapping.lisp.serializer;
9
10 import java.nio.ByteBuffer;
11 import java.util.ArrayList;
12
13 import org.apache.commons.lang3.BooleanUtils;
14 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
15 import org.opendaylight.lispflowmapping.lisp.type.LispMessageEnum;
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.control.plane.rev150314.MapRegister;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecord;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecordBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.mapregisternotification.MapRegisterBuilder;
22
23 /**
24  * This class deals with deserializing map register from udp to the java object.
25  */
26 public class MapRegisterSerializer {
27
28     private static final MapRegisterSerializer INSTANCE = new MapRegisterSerializer();
29
30     // Private constructor prevents instantiation from other classes
31     private MapRegisterSerializer() {
32     }
33
34     public static MapRegisterSerializer getInstance() {
35         return INSTANCE;
36     }
37
38     public ByteBuffer serialize(MapRegister mapRegister) {
39         int size = Length.HEADER_SIZE;
40         if (mapRegister.getAuthenticationData() != null) {
41             size += mapRegister.getAuthenticationData().length;
42         }
43         if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
44             size += Length.XTRID_SIZE + Length.SITEID_SIZE;
45         }
46         for (EidToLocatorRecord eidToLocatorRecord : mapRegister.getEidToLocatorRecord()) {
47             size += EidToLocatorRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord);
48         }
49
50         ByteBuffer registerBuffer = ByteBuffer.allocate(size);
51         registerBuffer.put((byte) ((byte) (LispMessageEnum.MapRegister.getValue() << 4) |
52                 ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY) |
53                 ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isXtrSiteIdPresent()), Flags.XTRSITEID)));
54         registerBuffer.position(registerBuffer.position() + Length.RES);
55         registerBuffer.put(ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_REPLY));
56         registerBuffer.put((byte) mapRegister.getEidToLocatorRecord().size());
57         registerBuffer.putLong(NumberUtil.asLong(mapRegister.getNonce()));
58         registerBuffer.putShort(NumberUtil.asShort(mapRegister.getKeyId()));
59
60         if (mapRegister.getAuthenticationData() != null) {
61             registerBuffer.putShort((short) mapRegister.getAuthenticationData().length);
62             registerBuffer.put(mapRegister.getAuthenticationData());
63         } else {
64             registerBuffer.putShort((short) 0);
65         }
66         for (EidToLocatorRecord eidToLocatorRecord : mapRegister.getEidToLocatorRecord()) {
67             EidToLocatorRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord);
68         }
69
70         if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
71             registerBuffer.put(mapRegister.getXtrId());
72             registerBuffer.put(mapRegister.getSiteId());
73         }
74         registerBuffer.clear();
75         return registerBuffer;
76     }
77
78     public MapRegister deserialize(ByteBuffer registerBuffer) {
79         try {
80             MapRegisterBuilder builder = new MapRegisterBuilder();
81             builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
82
83             byte typeAndFlags = registerBuffer.get();
84             boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
85             builder.setProxyMapReply(ByteUtil.extractBit(typeAndFlags, Flags.PROXY));
86             builder.setXtrSiteIdPresent(xtrSiteIdPresent);
87
88             registerBuffer.position(registerBuffer.position() + Length.RES);
89             builder.setWantMapNotify(ByteUtil.extractBit(registerBuffer.get(), Flags.WANT_MAP_REPLY));
90             byte recordCount = (byte) ByteUtil.getUnsignedByte(registerBuffer);
91             builder.setNonce(registerBuffer.getLong());
92             builder.setKeyId(registerBuffer.getShort());
93             short authenticationLength = registerBuffer.getShort();
94             byte[] authenticationData = new byte[authenticationLength];
95             registerBuffer.get(authenticationData);
96             builder.setAuthenticationData(authenticationData);
97
98             for (int i = 0; i < recordCount; i++) {
99                 builder.getEidToLocatorRecord().add(
100                         new EidToLocatorRecordBuilder(EidToLocatorRecordSerializer.getInstance().deserialize(registerBuffer)).build());
101             }
102
103             if (xtrSiteIdPresent) {
104                 byte[] xtrId  = new byte[Length.XTRID_SIZE];
105                 registerBuffer.get(xtrId);
106                 byte[] siteId = new byte[Length.SITEID_SIZE];
107                 registerBuffer.get(siteId);
108                 builder.setXtrId(xtrId);
109                 builder.setSiteId(siteId);
110             }
111             registerBuffer.limit(registerBuffer.position());
112             byte[] mapRegisterBytes = new byte[registerBuffer.position()];
113             registerBuffer.position(0);
114             registerBuffer.get(mapRegisterBytes);
115             return builder.build();
116         } catch (RuntimeException re) {
117             throw new LispSerializationException("Couldn't deserialize Map-Register (len=" + registerBuffer.capacity() + ")", re);
118         }
119
120     }
121
122     private interface Flags {
123         byte PROXY = 0x08;
124         byte XTRSITEID = 0x02;
125         byte WANT_MAP_REPLY = 0x01;
126     }
127
128     public interface Length {
129         int HEADER_SIZE = 16;
130         int XTRID_SIZE = 16;
131         int SITEID_SIZE = 8;
132         int RES = 1;
133     }
134 }