blob: 7f75181236de68e9c2edc3cbee125590d4e9890e [file] [log] [blame]
Jian Li451175e2016-07-19 23:22:20 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.lisp.msg.protocols;
17
Jian Li20850d32016-08-04 02:15:57 +090018import com.google.common.base.Objects;
Jian Lif59c0ad2016-08-02 18:11:30 +090019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
Jian Li451175e2016-07-19 23:22:20 +090021import io.netty.buffer.ByteBuf;
Jian Li47671902016-08-11 01:18:18 +090022import org.onlab.util.ByteOperator;
Jian Lif59c0ad2016-08-02 18:11:30 +090023import org.onlab.util.ImmutableByteSequence;
Jian Li26069e22016-08-10 22:00:52 +090024import org.onosproject.lisp.msg.exceptions.LispParseError;
Jian Lia7b394d2016-08-21 23:11:46 +090025import org.onosproject.lisp.msg.exceptions.LispReaderException;
Jian Li451175e2016-07-19 23:22:20 +090026
Jian Li719b3bf2016-07-22 00:38:29 +090027import java.util.List;
28
Jian Li20850d32016-08-04 02:15:57 +090029import static com.google.common.base.MoreObjects.toStringHelper;
30
Jian Li451175e2016-07-19 23:22:20 +090031/**
32 * Default LISP map register message class.
33 */
Jian Lif59c0ad2016-08-02 18:11:30 +090034public final class DefaultLispMapRegister implements LispMapRegister {
35
36 private final long nonce;
37 private final short keyId;
38 private final byte[] authenticationData;
39 private final byte recordCount;
40 private final List<LispMapRecord> mapRecords;
41 private final boolean proxyMapReply;
42 private final boolean wantMapNotify;
43
44 /**
45 * A private constructor that protects object instantiation from external.
46 *
47 * @param nonce nonce
48 * @param keyId key identifier
49 * @param authenticationData authentication data
50 * @param recordCount record count number
51 * @param mapRecords a collection of map records
52 * @param proxyMapReply proxy map reply flag
53 * @param wantMapNotify want map notify flag
54 */
55 private DefaultLispMapRegister(long nonce, short keyId,
56 byte[] authenticationData, byte recordCount,
57 List<LispMapRecord> mapRecords,
58 boolean proxyMapReply, boolean wantMapNotify) {
59 this.nonce = nonce;
60 this.keyId = keyId;
61 this.authenticationData = authenticationData;
62 this.recordCount = recordCount;
63 this.mapRecords = mapRecords;
64 this.proxyMapReply = proxyMapReply;
65 this.wantMapNotify = wantMapNotify;
66 }
67
Jian Li451175e2016-07-19 23:22:20 +090068 @Override
69 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090070 return LispType.LISP_MAP_REGISTER;
Jian Li451175e2016-07-19 23:22:20 +090071 }
72
73 @Override
74 public void writeTo(ByteBuf byteBuf) {
Jian Lif59c0ad2016-08-02 18:11:30 +090075 // TODO: serialize LispMapRegister message
Jian Li451175e2016-07-19 23:22:20 +090076 }
77
78 @Override
79 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090080 return new DefaultRegisterBuilder();
Jian Li451175e2016-07-19 23:22:20 +090081 }
Jian Li719b3bf2016-07-22 00:38:29 +090082
83 @Override
84 public boolean isProxyMapReply() {
Jian Lif59c0ad2016-08-02 18:11:30 +090085 return proxyMapReply;
Jian Li719b3bf2016-07-22 00:38:29 +090086 }
87
88 @Override
89 public boolean isWantMapNotify() {
Jian Lif59c0ad2016-08-02 18:11:30 +090090 return wantMapNotify;
Jian Li719b3bf2016-07-22 00:38:29 +090091 }
92
93 @Override
94 public byte getRecordCount() {
Jian Lif59c0ad2016-08-02 18:11:30 +090095 return recordCount;
Jian Li719b3bf2016-07-22 00:38:29 +090096 }
97
98 @Override
99 public long getNonce() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900100 return nonce;
Jian Li719b3bf2016-07-22 00:38:29 +0900101 }
102
103 @Override
104 public short getKeyId() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900105 return keyId;
Jian Li719b3bf2016-07-22 00:38:29 +0900106 }
107
108 @Override
109 public byte[] getAuthenticationData() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900110 return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
Jian Li719b3bf2016-07-22 00:38:29 +0900111 }
112
113 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900114 public List<LispMapRecord> getMapRecords() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900115 return ImmutableList.copyOf(mapRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900116 }
117
Jian Li20850d32016-08-04 02:15:57 +0900118 @Override
119 public String toString() {
120 return toStringHelper(this)
121 .add("type", getType())
122 .add("nonce", nonce)
123 .add("recordCount", recordCount)
124 .add("keyId", keyId)
125 .add("mapRecords", mapRecords)
126 .add("proxyMapReply", proxyMapReply)
127 .add("wantMapNotify", wantMapNotify).toString();
128 }
129
130 @Override
131 public boolean equals(Object o) {
132 if (this == o) {
133 return true;
134 }
135 if (o == null || getClass() != o.getClass()) {
136 return false;
137 }
138
139 DefaultLispMapRegister that = (DefaultLispMapRegister) o;
140 return Objects.equal(nonce, that.nonce) &&
141 Objects.equal(recordCount, that.recordCount) &&
142 Objects.equal(keyId, that.keyId) &&
143 Objects.equal(authenticationData, that.authenticationData) &&
144 Objects.equal(proxyMapReply, that.proxyMapReply) &&
145 Objects.equal(wantMapNotify, that.wantMapNotify);
146 }
147
148 @Override
149 public int hashCode() {
150 return Objects.hashCode(nonce, recordCount, keyId, authenticationData,
151 proxyMapReply, wantMapNotify);
152 }
153
Jian Li719b3bf2016-07-22 00:38:29 +0900154 public static final class DefaultRegisterBuilder implements RegisterBuilder {
155
Jian Lif59c0ad2016-08-02 18:11:30 +0900156 private long nonce;
157 private short keyId;
158 private byte[] authenticationData;
159 private byte recordCount;
Jian Li47671902016-08-11 01:18:18 +0900160 private List<LispMapRecord> mapRecords;
Jian Lif59c0ad2016-08-02 18:11:30 +0900161 private boolean proxyMapReply;
162 private boolean wantMapNotify;
Jian Li719b3bf2016-07-22 00:38:29 +0900163
164 @Override
165 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900166 return LispType.LISP_MAP_REGISTER;
Jian Li719b3bf2016-07-22 00:38:29 +0900167 }
168
169 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900170 public RegisterBuilder withIsProxyMapReply(boolean proxyMapReply) {
171 this.proxyMapReply = proxyMapReply;
172 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900173 }
174
175 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900176 public RegisterBuilder withIsWantMapNotify(boolean wantMapNotify) {
177 this.wantMapNotify = wantMapNotify;
178 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900179 }
180
181 @Override
182 public RegisterBuilder withRecordCount(byte recordCount) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900183 this.recordCount = recordCount;
184 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900185 }
186
187 @Override
188 public RegisterBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900189 this.nonce = nonce;
190 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900191 }
192
193 @Override
194 public RegisterBuilder withKeyId(short keyId) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900195 this.keyId = keyId;
196 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900197 }
198
199 @Override
200 public RegisterBuilder withAuthenticationData(byte[] authenticationData) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900201 this.authenticationData = authenticationData;
202 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900203 }
204
205 @Override
Jian Li47671902016-08-11 01:18:18 +0900206 public RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords) {
207 this.mapRecords = ImmutableList.copyOf(mapRecords);
Jian Lif59c0ad2016-08-02 18:11:30 +0900208 return this;
209 }
210
211 @Override
Jian Li525fded2016-08-04 01:15:33 +0900212 public LispMapRegister build() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900213 return new DefaultLispMapRegister(nonce, keyId, authenticationData,
214 recordCount, mapRecords, proxyMapReply, wantMapNotify);
Jian Li719b3bf2016-07-22 00:38:29 +0900215 }
216 }
Jian Li26069e22016-08-10 22:00:52 +0900217
218 /**
219 * A private LISP message reader for MapRegister message.
220 */
221 private static class RegisterReader implements LispMessageReader<LispMapRegister> {
222
Jian Li47671902016-08-11 01:18:18 +0900223 private static final int PROXY_MAP_REPLY_INDEX = 3;
224 private static final int WANT_MAP_NOTIFY_INDEX = 0;
225 private static final int RESERVED_SKIP_LENGTH = 1;
226
Jian Li26069e22016-08-10 22:00:52 +0900227 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900228 public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900229
230 if (byteBuf.readerIndex() != 0) {
231 return null;
232 }
233
234 // proxyMapReply -> 1 bit
235 boolean proxyMapReplyFlag = ByteOperator.getBit(byteBuf.readByte(), PROXY_MAP_REPLY_INDEX);
236
237 // let's skip the reserved field
238 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
239
240 byte reservedWithFlag = byteBuf.readByte();
241
242 // wantMapReply -> 1 bit
243 boolean wantMapNotifyFlag = ByteOperator.getBit(reservedWithFlag, WANT_MAP_NOTIFY_INDEX);
244
245 // record count -> 8 bits
246 byte recordCount = (byte) byteBuf.readUnsignedByte();
247
248 // nonce -> 64 bits
249 long nonce = byteBuf.readLong();
250
251 // keyId -> 16 bits
252 short keyId = byteBuf.readShort();
253
254 // authenticationDataLength -> 16 bits
255 short authLength = byteBuf.readShort();
256
257 // authenticationData -> depends on the authenticationDataLength
258 byte[] authData = new byte[authLength];
259 byteBuf.readBytes(authData);
260
261 List<LispMapRecord> mapRecords = Lists.newArrayList();
262 for (int i = 0; i < recordCount; i++) {
263 mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
264 }
265
266 return new DefaultRegisterBuilder()
267 .withIsProxyMapReply(proxyMapReplyFlag)
268 .withIsWantMapNotify(wantMapNotifyFlag)
269 .withRecordCount(recordCount)
270 .withNonce(nonce)
271 .withKeyId(keyId)
272 .withAuthenticationData(authData)
273 .withMapRecords(mapRecords)
274 .build();
Jian Li26069e22016-08-10 22:00:52 +0900275 }
276 }
Jian Li451175e2016-07-19 23:22:20 +0900277}