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