blob: a180a2dabf9e6a0b51be1e6c58c89521cb3e453f [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 Lia7b394d2016-08-21 23:11:46 +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 Li26069e22016-08-10 22:00:52 +090023import org.onosproject.lisp.msg.exceptions.LispParseError;
Jian Lia7b394d2016-08-21 23:11:46 +090024import org.onosproject.lisp.msg.exceptions.LispReaderException;
25
26import java.util.List;
Jian Li451175e2016-07-19 23:22:20 +090027
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 reply message class.
32 */
Jian Lif59c0ad2016-08-02 18:11:30 +090033public final class DefaultLispMapReply implements LispMapReply {
34
35 private final long nonce;
36 private final byte recordCount;
37 private final boolean probe;
38 private final boolean etr;
39 private final boolean security;
Jian Lia7b394d2016-08-21 23:11:46 +090040 private final List<LispMapRecord> mapRecords;
Jian Lif59c0ad2016-08-02 18:11:30 +090041
42 /**
43 * A private constructor that protects object instantiation from external.
44 *
45 * @param nonce nonce
46 * @param recordCount record count number
47 * @param probe probe flag
48 * @param etr etr flag
49 * @param security security flag
50 */
51 private DefaultLispMapReply(long nonce, byte recordCount, boolean probe,
Jian Lia7b394d2016-08-21 23:11:46 +090052 boolean etr, boolean security, List<LispMapRecord> mapRecords) {
Jian Lif59c0ad2016-08-02 18:11:30 +090053 this.nonce = nonce;
54 this.recordCount = recordCount;
55 this.probe = probe;
56 this.etr = etr;
57 this.security = security;
Jian Lia7b394d2016-08-21 23:11:46 +090058 this.mapRecords = mapRecords;
Jian Lif59c0ad2016-08-02 18:11:30 +090059 }
60
Jian Li451175e2016-07-19 23:22:20 +090061 @Override
62 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090063 return LispType.LISP_MAP_REPLY;
Jian Li451175e2016-07-19 23:22:20 +090064 }
65
66 @Override
67 public void writeTo(ByteBuf byteBuf) {
Jian Lif59c0ad2016-08-02 18:11:30 +090068 // TODO: serialize LispMapReply message
Jian Li451175e2016-07-19 23:22:20 +090069 }
70
71 @Override
72 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090073 return new DefaultReplyBuilder();
Jian Li451175e2016-07-19 23:22:20 +090074 }
Jian Li719b3bf2016-07-22 00:38:29 +090075
76 @Override
77 public boolean isProbe() {
Jian Lif59c0ad2016-08-02 18:11:30 +090078 return this.probe;
Jian Li719b3bf2016-07-22 00:38:29 +090079 }
80
81 @Override
82 public boolean isEtr() {
Jian Lif59c0ad2016-08-02 18:11:30 +090083 return this.etr;
Jian Li719b3bf2016-07-22 00:38:29 +090084 }
85
86 @Override
87 public boolean isSecurity() {
Jian Lif59c0ad2016-08-02 18:11:30 +090088 return this.security;
Jian Li719b3bf2016-07-22 00:38:29 +090089 }
90
91 @Override
92 public byte getRecordCount() {
Jian Lif59c0ad2016-08-02 18:11:30 +090093 return this.recordCount;
Jian Li719b3bf2016-07-22 00:38:29 +090094 }
95
96 @Override
97 public long getNonce() {
Jian Lif59c0ad2016-08-02 18:11:30 +090098 return this.nonce;
Jian Li719b3bf2016-07-22 00:38:29 +090099 }
100
Jian Li20850d32016-08-04 02:15:57 +0900101 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900102 public List<LispMapRecord> getMapRecords() {
103 return ImmutableList.copyOf(mapRecords);
104 }
105
106 @Override
Jian Li20850d32016-08-04 02:15:57 +0900107 public String toString() {
108 return toStringHelper(this)
109 .add("type", getType())
110 .add("nonce", nonce)
111 .add("recordCount", recordCount)
112 .add("probe", probe)
113 .add("etr", etr)
Jian Lia7b394d2016-08-21 23:11:46 +0900114 .add("security", security)
115 .add("map records", mapRecords).toString();
Jian Li20850d32016-08-04 02:15:57 +0900116 }
117
118 @Override
119 public boolean equals(Object o) {
120 if (this == o) {
121 return true;
122 }
123 if (o == null || getClass() != o.getClass()) {
124 return false;
125 }
126 DefaultLispMapReply that = (DefaultLispMapReply) o;
127 return Objects.equal(nonce, that.nonce) &&
128 Objects.equal(recordCount, that.recordCount) &&
129 Objects.equal(probe, that.probe) &&
130 Objects.equal(etr, that.etr) &&
Jian Lia7b394d2016-08-21 23:11:46 +0900131 Objects.equal(security, that.security) &&
132 Objects.equal(mapRecords, that.mapRecords);
Jian Li20850d32016-08-04 02:15:57 +0900133 }
134
135 @Override
136 public int hashCode() {
Jian Lia7b394d2016-08-21 23:11:46 +0900137 return Objects.hashCode(nonce, recordCount, probe, etr, security, mapRecords);
Jian Li20850d32016-08-04 02:15:57 +0900138 }
139
Jian Li719b3bf2016-07-22 00:38:29 +0900140 public static final class DefaultReplyBuilder implements ReplyBuilder {
141
Jian Lif59c0ad2016-08-02 18:11:30 +0900142 private long nonce;
143 private byte recordCount;
144 private boolean probe;
145 private boolean etr;
146 private boolean security;
Jian Lia7b394d2016-08-21 23:11:46 +0900147 private List<LispMapRecord> mapRecords;
Jian Li719b3bf2016-07-22 00:38:29 +0900148
149 @Override
150 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900151 return LispType.LISP_MAP_REPLY;
Jian Li719b3bf2016-07-22 00:38:29 +0900152 }
153
154 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900155 public ReplyBuilder withIsProbe(boolean probe) {
156 this.probe = probe;
157 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900158 }
159
160 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900161 public ReplyBuilder withIsEtr(boolean etr) {
162 this.etr = etr;
163 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900164 }
165
166 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900167 public ReplyBuilder withIsSecurity(boolean security) {
168 this.security = security;
169 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900170 }
171
172 @Override
173 public ReplyBuilder withRecordCount(byte recordCount) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900174 this.recordCount = recordCount;
175 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900176 }
177
178 @Override
179 public ReplyBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900180 this.nonce = nonce;
181 return this;
182 }
183
184 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900185 public ReplyBuilder withMapRecords(List<LispMapRecord> mapRecords) {
186 this.mapRecords = ImmutableList.copyOf(mapRecords);
187 return this;
188 }
189
190 @Override
Jian Li525fded2016-08-04 01:15:33 +0900191 public LispMapReply build() {
Jian Lia7b394d2016-08-21 23:11:46 +0900192 return new DefaultLispMapReply(nonce, recordCount, probe, etr, security, mapRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900193 }
194 }
Jian Li26069e22016-08-10 22:00:52 +0900195
196 /**
197 * A private LISP message reader for MapReply message.
198 */
199 private static class ReplyReader implements LispMessageReader<LispMapReply> {
200
Jian Li47671902016-08-11 01:18:18 +0900201 private static final int PROBE_INDEX = 3;
202 private static final int ETR_INDEX = 2;
203 private static final int SECURITY_INDEX = 1;
204 private static final int RESERVED_SKIP_LENGTH = 2;
205
Jian Li26069e22016-08-10 22:00:52 +0900206 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900207 public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900208
209 if (byteBuf.readerIndex() != 0) {
210 return null;
211 }
212
213 byte typeWithFlags = byteBuf.readByte();
214
215 // probe -> 1 bit
216 boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
217
218 // etr -> 1bit
219 boolean etr = ByteOperator.getBit(typeWithFlags, ETR_INDEX);
220
221 // security -> 1 bit
222 boolean security = ByteOperator.getBit(typeWithFlags, SECURITY_INDEX);
223
224 // skip two bytes as they represent reserved fields
225 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
226
227 // record count -> 8 bits
228 byte recordCount = (byte) byteBuf.readUnsignedByte();
229
230 // nonce -> 64 bits
231 long nonce = byteBuf.readLong();
232
Jian Lia7b394d2016-08-21 23:11:46 +0900233 List<LispMapRecord> mapRecords = Lists.newArrayList();
234 for (int i = 0; i < recordCount; i++) {
235 mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
236 }
Jian Li47671902016-08-11 01:18:18 +0900237
238 return new DefaultReplyBuilder()
239 .withIsProbe(probe)
240 .withIsEtr(etr)
241 .withIsSecurity(security)
242 .withRecordCount(recordCount)
243 .withNonce(nonce)
244 .build();
Jian Li26069e22016-08-10 22:00:52 +0900245 }
246 }
Jian Li451175e2016-07-19 23:22:20 +0900247}