d982892b28ff8f68f8b1a146d0550b44a37f6bb9
[lispflowmapping.git] / mappingservice / api / src / main / java / org / opendaylight / lispflowmapping / type / lisp / address / LispLCAFAddress.java
1 /*
2  * Copyright (c) 2013 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.type.lisp.address;
9
10 import java.lang.reflect.InvocationTargetException;
11 import java.lang.reflect.Method;
12 import java.nio.ByteBuffer;
13
14 import org.opendaylight.lispflowmapping.type.AddressFamilyNumberEnum;
15 import org.opendaylight.lispflowmapping.type.LispCanonicalAddressFormatEnum;
16 import org.opendaylight.lispflowmapping.type.exception.LispMalformedPacketException;
17
18 public abstract class LispLCAFAddress extends LispAddress {
19
20     protected LispCanonicalAddressFormatEnum lcafType;
21     protected byte res2;
22
23     protected LispLCAFAddress(ByteBuffer buffer) {
24         super(AddressFamilyNumberEnum.LCAF);
25     }
26
27     public LispLCAFAddress(LispCanonicalAddressFormatEnum lcafType, byte res2) {
28         super(AddressFamilyNumberEnum.LCAF);
29         this.lcafType = lcafType;
30         this.res2 = res2;
31     }
32
33     public static LispLCAFAddress valueOf(ByteBuffer buffer) {
34         buffer.position(buffer.position() + Length.RES + Length.FLAGS);
35         byte lispCode = buffer.get();
36         LispCanonicalAddressFormatEnum lcafType = LispCanonicalAddressFormatEnum.valueOf(lispCode);
37         byte res2 = buffer.get();
38         short length = buffer.getShort();
39
40         Class<? extends LispAddress> addressClass = lcafType.getLcafClass();
41         if (addressClass == null) {
42             throw new LispMalformedPacketException("Unknown LispLCAFAddress type=" + lispCode);
43         }
44         Method valueOfMethod;
45         Throwable t = null;
46         try {
47             valueOfMethod = addressClass.getMethod("valueOf", byte.class, short.class, ByteBuffer.class);
48             return (LispLCAFAddress) valueOfMethod.invoke(null, res2, length, buffer);
49         } catch (NoSuchMethodException e) {
50             t = e;
51         } catch (SecurityException e) {
52             t = e;
53         } catch (IllegalAccessException e) {
54             t = e;
55         } catch (IllegalArgumentException e) {
56             t = e;
57         } catch (InvocationTargetException e) {
58             t = e;
59         }
60         throw new LispMalformedPacketException("Couldn't parse LispLCAFAddress type=" + lispCode, t);
61     }
62
63     @Override
64     public final int getAddressSize() {
65         return super.getAddressSize() + Length.LCAF_HEADER + getLcafLength();
66     }
67
68     public abstract short getLcafLength();
69
70     @Override
71     protected void internalSerialize(ByteBuffer buffer) {
72         super.internalSerialize(buffer);
73         buffer.putShort((short) 0); // RES + Flags.
74         buffer.put(lcafType.getLispCode());
75         buffer.put(getRes2());
76         buffer.putShort(getLcafLength());
77     }
78
79     public LispCanonicalAddressFormatEnum getType() {
80         return lcafType;
81     }
82
83     public byte getRes2() {
84         return res2;
85     }
86
87     @Override
88     public int hashCode() {
89         final int prime = 31;
90         int result = super.hashCode();
91         result = prime * result + ((lcafType == null) ? 0 : lcafType.hashCode());
92         result = prime * result + res2;
93         return result;
94     }
95
96     @Override
97     public boolean equals(Object obj) {
98         if (this == obj)
99             return true;
100         if (!super.equals(obj))
101             return false;
102         if (getClass() != obj.getClass())
103             return false;
104         LispLCAFAddress other = (LispLCAFAddress) obj;
105         if (lcafType != other.lcafType)
106             return false;
107         if (res2 != other.res2)
108             return false;
109         return true;
110     }
111
112     @Override
113     public String toString() {
114         return "[lcafType=" + lcafType + ", res2=" + res2 + "]";
115     }
116
117     private interface Length {
118         int RES = 1;
119         int FLAGS = 1;
120
121         int LCAF_HEADER = 6;
122     }
123 }