blob: 058db1080c28e5523fff850e89bc4500bf028566 [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 Li451175e2016-07-19 23:22:20 +090025
Jian Li719b3bf2016-07-22 00:38:29 +090026import java.util.List;
27
Jian Li20850d32016-08-04 02:15:57 +090028import static com.google.common.base.MoreObjects.toStringHelper;
29
Jian Li451175e2016-07-19 23:22:20 +090030/**
31 * Default LISP map register message class.
32 */
Jian Lif59c0ad2016-08-02 18:11:30 +090033public final class DefaultLispMapRegister implements LispMapRegister {
34
35 private final long nonce;
36 private final short keyId;
37 private final byte[] authenticationData;
38 private final byte recordCount;
39 private final List<LispMapRecord> mapRecords;
40 private final boolean proxyMapReply;
41 private final boolean wantMapNotify;
42
43 /**
44 * A private constructor that protects object instantiation from external.
45 *
46 * @param nonce nonce
47 * @param keyId key identifier
48 * @param authenticationData authentication data
49 * @param recordCount record count number
50 * @param mapRecords a collection of map records
51 * @param proxyMapReply proxy map reply flag
52 * @param wantMapNotify want map notify flag
53 */
54 private DefaultLispMapRegister(long nonce, short keyId,
55 byte[] authenticationData, byte recordCount,
56 List<LispMapRecord> mapRecords,
57 boolean proxyMapReply, boolean wantMapNotify) {
58 this.nonce = nonce;
59 this.keyId = keyId;
60 this.authenticationData = authenticationData;
61 this.recordCount = recordCount;
62 this.mapRecords = mapRecords;
63 this.proxyMapReply = proxyMapReply;
64 this.wantMapNotify = wantMapNotify;
65 }
66
Jian Li451175e2016-07-19 23:22:20 +090067 @Override
68 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090069 return LispType.LISP_MAP_REGISTER;
Jian Li451175e2016-07-19 23:22:20 +090070 }
71
72 @Override
73 public void writeTo(ByteBuf byteBuf) {
Jian Lif59c0ad2016-08-02 18:11:30 +090074 // TODO: serialize LispMapRegister message
Jian Li451175e2016-07-19 23:22:20 +090075 }
76
77 @Override
78 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090079 return new DefaultRegisterBuilder();
Jian Li451175e2016-07-19 23:22:20 +090080 }
Jian Li719b3bf2016-07-22 00:38:29 +090081
82 @Override
83 public boolean isProxyMapReply() {
Jian Lif59c0ad2016-08-02 18:11:30 +090084 return proxyMapReply;
Jian Li719b3bf2016-07-22 00:38:29 +090085 }
86
87 @Override
88 public boolean isWantMapNotify() {
Jian Lif59c0ad2016-08-02 18:11:30 +090089 return wantMapNotify;
Jian Li719b3bf2016-07-22 00:38:29 +090090 }
91
92 @Override
93 public byte getRecordCount() {
Jian Lif59c0ad2016-08-02 18:11:30 +090094 return recordCount;
Jian Li719b3bf2016-07-22 00:38:29 +090095 }
96
97 @Override
98 public long getNonce() {
Jian Lif59c0ad2016-08-02 18:11:30 +090099 return nonce;
Jian Li719b3bf2016-07-22 00:38:29 +0900100 }
101
102 @Override
103 public short getKeyId() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900104 return keyId;
Jian Li719b3bf2016-07-22 00:38:29 +0900105 }
106
107 @Override
108 public byte[] getAuthenticationData() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900109 return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
Jian Li719b3bf2016-07-22 00:38:29 +0900110 }
111
112 @Override
Jian Li10a09062016-07-26 23:58:50 +0900113 public List<LispMapRecord> getLispRecords() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900114 return ImmutableList.copyOf(mapRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900115 }
116
Jian Li20850d32016-08-04 02:15:57 +0900117 @Override
118 public String toString() {
119 return toStringHelper(this)
120 .add("type", getType())
121 .add("nonce", nonce)
122 .add("recordCount", recordCount)
123 .add("keyId", keyId)
124 .add("mapRecords", mapRecords)
125 .add("proxyMapReply", proxyMapReply)
126 .add("wantMapNotify", wantMapNotify).toString();
127 }
128
129 @Override
130 public boolean equals(Object o) {
131 if (this == o) {
132 return true;
133 }
134 if (o == null || getClass() != o.getClass()) {
135 return false;
136 }
137
138 DefaultLispMapRegister that = (DefaultLispMapRegister) o;
139 return Objects.equal(nonce, that.nonce) &&
140 Objects.equal(recordCount, that.recordCount) &&
141 Objects.equal(keyId, that.keyId) &&
142 Objects.equal(authenticationData, that.authenticationData) &&
143 Objects.equal(proxyMapReply, that.proxyMapReply) &&
144 Objects.equal(wantMapNotify, that.wantMapNotify);
145 }
146
147 @Override
148 public int hashCode() {
149 return Objects.hashCode(nonce, recordCount, keyId, authenticationData,
150 proxyMapReply, wantMapNotify);
151 }
152
Jian Li719b3bf2016-07-22 00:38:29 +0900153 public static final class DefaultRegisterBuilder implements RegisterBuilder {
154
Jian Lif59c0ad2016-08-02 18:11:30 +0900155 private long nonce;
156 private short keyId;
157 private byte[] authenticationData;
158 private byte recordCount;
Jian Li47671902016-08-11 01:18:18 +0900159 private List<LispMapRecord> mapRecords;
Jian Lif59c0ad2016-08-02 18:11:30 +0900160 private boolean proxyMapReply;
161 private boolean wantMapNotify;
Jian Li719b3bf2016-07-22 00:38:29 +0900162
163 @Override
164 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900165 return LispType.LISP_MAP_REGISTER;
Jian Li719b3bf2016-07-22 00:38:29 +0900166 }
167
168 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900169 public RegisterBuilder withIsProxyMapReply(boolean proxyMapReply) {
170 this.proxyMapReply = proxyMapReply;
171 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900172 }
173
174 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900175 public RegisterBuilder withIsWantMapNotify(boolean wantMapNotify) {
176 this.wantMapNotify = wantMapNotify;
177 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900178 }
179
180 @Override
181 public RegisterBuilder withRecordCount(byte recordCount) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900182 this.recordCount = recordCount;
183 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900184 }
185
186 @Override
187 public RegisterBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900188 this.nonce = nonce;
189 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900190 }
191
192 @Override
193 public RegisterBuilder withKeyId(short keyId) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900194 this.keyId = keyId;
195 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900196 }
197
198 @Override
199 public RegisterBuilder withAuthenticationData(byte[] authenticationData) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900200 this.authenticationData = authenticationData;
201 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900202 }
203
204 @Override
Jian Li47671902016-08-11 01:18:18 +0900205 public RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords) {
206 this.mapRecords = ImmutableList.copyOf(mapRecords);
Jian Lif59c0ad2016-08-02 18:11:30 +0900207 return this;
208 }
209
210 @Override
Jian Li525fded2016-08-04 01:15:33 +0900211 public LispMapRegister build() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900212 return new DefaultLispMapRegister(nonce, keyId, authenticationData,
213 recordCount, mapRecords, proxyMapReply, wantMapNotify);
Jian Li719b3bf2016-07-22 00:38:29 +0900214 }
215 }
Jian Li26069e22016-08-10 22:00:52 +0900216
217 /**
218 * A private LISP message reader for MapRegister message.
219 */
220 private static class RegisterReader implements LispMessageReader<LispMapRegister> {
221
Jian Li47671902016-08-11 01:18:18 +0900222 private static final int PROXY_MAP_REPLY_INDEX = 3;
223 private static final int WANT_MAP_NOTIFY_INDEX = 0;
224 private static final int RESERVED_SKIP_LENGTH = 1;
225
Jian Li26069e22016-08-10 22:00:52 +0900226 @Override
227 public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError {
Jian Li47671902016-08-11 01:18:18 +0900228
229 if (byteBuf.readerIndex() != 0) {
230 return null;
231 }
232
233 // proxyMapReply -> 1 bit
234 boolean proxyMapReplyFlag = ByteOperator.getBit(byteBuf.readByte(), PROXY_MAP_REPLY_INDEX);
235
236 // let's skip the reserved field
237 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
238
239 byte reservedWithFlag = byteBuf.readByte();
240
241 // wantMapReply -> 1 bit
242 boolean wantMapNotifyFlag = ByteOperator.getBit(reservedWithFlag, WANT_MAP_NOTIFY_INDEX);
243
244 // record count -> 8 bits
245 byte recordCount = (byte) byteBuf.readUnsignedByte();
246
247 // nonce -> 64 bits
248 long nonce = byteBuf.readLong();
249
250 // keyId -> 16 bits
251 short keyId = byteBuf.readShort();
252
253 // authenticationDataLength -> 16 bits
254 short authLength = byteBuf.readShort();
255
256 // authenticationData -> depends on the authenticationDataLength
257 byte[] authData = new byte[authLength];
258 byteBuf.readBytes(authData);
259
260 List<LispMapRecord> mapRecords = Lists.newArrayList();
261 for (int i = 0; i < recordCount; i++) {
262 mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
263 }
264
265 return new DefaultRegisterBuilder()
266 .withIsProxyMapReply(proxyMapReplyFlag)
267 .withIsWantMapNotify(wantMapNotifyFlag)
268 .withRecordCount(recordCount)
269 .withNonce(nonce)
270 .withKeyId(keyId)
271 .withAuthenticationData(authData)
272 .withMapRecords(mapRecords)
273 .build();
Jian Li26069e22016-08-10 22:00:52 +0900274 }
275 }
Jian Li451175e2016-07-19 23:22:20 +0900276}