blob: 83f2ef2800d9861adb499938c7568f0efce3eb0b [file] [log] [blame]
David K. Bainbridged77028f2017-08-01 12:47:55 -07001/*
Brian O'Connor4d084702017-08-03 22:45:58 -07002 * Copyright 2017-present Open Networking Foundation
David K. Bainbridged77028f2017-08-01 12:47:55 -07003 *
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 */
developere400c582020-03-24 19:42:08 +010016package org.opencord.igmpproxy.impl;
ke han81a38b92017-03-10 18:41:44 +080017
ke han81a38b92017-03-10 18:41:44 +080018import org.onlab.packet.Ip4Address;
19import org.onosproject.net.DeviceId;
Esin Karaman00e16b72020-02-21 10:32:39 +000020import org.onosproject.net.PortNumber;
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000021import org.opencord.igmpproxy.impl.state.DelayMember;
22import org.opencord.igmpproxy.impl.state.IdleMember;
23import org.opencord.igmpproxy.impl.state.NonMember;
24import org.opencord.igmpproxy.statemachine.StateMachine;
25import org.opencord.igmpproxy.statemachine.State;
26import org.opencord.igmpproxy.statemachine.StateMachineId;
ke han81a38b92017-03-10 18:41:44 +080027
Esin Karamanb38700c2019-09-17 13:01:25 +000028import java.util.concurrent.atomic.AtomicInteger;
ke han81a38b92017-03-10 18:41:44 +080029
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000030
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000031/**
32 * State machine implementation.
33 */
34public final class SingleStateMachine implements StateMachine {
35 public static final int DEFAULT_MAX_RESP = 0xfffffff;
36
37 private StateMachineId stateMachineId;
38 private int currentState;
39
ke han81a38b92017-03-10 18:41:44 +080040 private Ip4Address srcIp;
Esin Karaman00e16b72020-02-21 10:32:39 +000041 private PortNumber upLinkPort;
ke han81a38b92017-03-10 18:41:44 +080042
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000043 private AtomicInteger timeOut; // unit is 1 second
44 private State[] states;
ke han81a38b92017-03-10 18:41:44 +080045 private int[] nonTransition =
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000046 {State.STATE_DELAY, State.STATE_NON,
47 State.STATE_NON, State.STATE_NON};
ke han81a38b92017-03-10 18:41:44 +080048 private int[] delayTransition =
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000049 {State.STATE_DELAY, State.STATE_NON,
50 State.STATE_DELAY, State.STATE_IDLE};
ke han81a38b92017-03-10 18:41:44 +080051 private int[] idleTransition =
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000052 {State.STATE_IDLE, State.STATE_NON,
53 State.STATE_DELAY, State.STATE_IDLE};
ke han81a38b92017-03-10 18:41:44 +080054 //THE TRANSITION TABLE
55 private int[][] transition =
56 {nonTransition, delayTransition, idleTransition};
ke han81a38b92017-03-10 18:41:44 +080057
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000058 /**
59 * Constructor for serializer.
60 */
61 private SingleStateMachine() {
62 this.stateMachineId = null;
63 this.srcIp = null;
64 this.upLinkPort = null;
65 this.timeOut = null;
66 this.states = null;
67 }
68
69 /**
70 * Constructor of single state machine.
71 *
72 * @param deviceId device id of state-machine
73 * @param groupIp group id of state-machine
74 * @param srcIp source ip of state-machine
75 * @param upLinkPort uplink port of state-machine
76 */
77 public SingleStateMachine(DeviceId deviceId,
78 Ip4Address groupIp,
79 Ip4Address srcIp,
80 PortNumber upLinkPort) {
81 this.stateMachineId = StateMachineId.of(deviceId, groupIp);
82 this.srcIp = srcIp;
Esin Karaman00e16b72020-02-21 10:32:39 +000083 this.upLinkPort = upLinkPort;
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000084 this.currentState = State.STATE_NON;
85 this.timeOut = null;
86 this.states = new State[]{new NonMember(this), new DelayMember(this), new IdleMember(this)};
ke han81a38b92017-03-10 18:41:44 +080087 }
88
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +000089 /**
90 * Constructor of single state machine.
91 *
92 * @param machineId id of state-machine
93 * @param srcIp source ip of state-machine
94 * @param upLinkPort uplink port of state-machine
95 * @param currentState current state of state-machine
96 * @param timeout timeout value of state-machine
97 */
98 public SingleStateMachine(StateMachineId machineId,
99 Ip4Address srcIp,
100 PortNumber upLinkPort,
101 int currentState,
102 Integer timeout) {
103 this.stateMachineId = machineId;
104 this.srcIp = srcIp;
105 this.upLinkPort = upLinkPort;
106 this.currentState = currentState;
107 if (timeout != null) {
108 createTimeOut(timeout);
ke han81a38b92017-03-10 18:41:44 +0800109 } else {
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000110 this.timeOut = null;
ke han81a38b92017-03-10 18:41:44 +0800111 }
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000112 this.states = new State[]{new NonMember(this), new DelayMember(this), new IdleMember(this)};
ke han81a38b92017-03-10 18:41:44 +0800113 }
114
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000115 @Override
116 public StateMachineId getStateMachineId() {
117 return this.stateMachineId;
ke han81a38b92017-03-10 18:41:44 +0800118 }
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000119
120 @Override
121 public Ip4Address getGroupIp() {
122 return this.stateMachineId.getGroupIp();
123 }
124
125 @Override
126 public DeviceId getDeviceId() {
127 return this.stateMachineId.getDeviceId();
128 }
129
130
131 @Override
132 public Ip4Address getSrcIp() {
133 return srcIp;
134 }
135
136 public PortNumber getUpLinkPort() {
137 return upLinkPort;
138 }
139
140 @Override
ke han81a38b92017-03-10 18:41:44 +0800141 public int currentState() {
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000142 return this.currentState;
143 }
144
145 public Integer getTimeOut() {
146 return timeOut == null ? null : timeOut.get();
147 }
148
149 @Override
150 public void increaseTimeOut() {
151 this.timeOut.getAndIncrement();
152 }
153
154 @Override
155 public void decreaseTimeOut() {
156 this.timeOut.getAndDecrement();
157 }
158
159 @Override
160 public void setMaxTimeout() {
161 this.timeOut.set(DEFAULT_MAX_RESP);
162 }
163
164 @Override
165 public void startTimer(int timeout) {
166 createTimeOut(timeout);
167 }
168
169 @Override
170 public void resetTimer(int timeout) {
171 setTimeOut(timeout);
172 }
173
174 @Override
175 public void destroyTimer() {
176 setTimeOut(null);
177 }
178
179 @Override
180 public void join(boolean messageOutAllowed) {
181 if (messageOutAllowed) {
182 State state = states[currentState];
183 state.join();
184 }
185 next(State.TRANSITION_JOIN);
186 }
187
188 @Override
189 public void leave(boolean messageOutAllowed) {
190 if (messageOutAllowed) {
191 State state = states[currentState];
192 state.leave();
193 }
194 next(State.TRANSITION_LEAVE);
195 }
196
197 @Override
198 public void query(int maxResp) {
199 State state = states[currentState];
200 state.query(maxResp);
201 next(State.TRANSITION_QUERY);
202 }
203
204 @Override
205 public void timeOut(boolean sendQuery) {
206 if (sendQuery) {
207 State state = states[currentState];
208 state.timeOut();
209 }
210 next(State.TRANSITION_TIMEOUT);
ke han81a38b92017-03-10 18:41:44 +0800211 }
212
213 private void next(int msg) {
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000214 this.currentState = transition[currentState][msg];
ke han81a38b92017-03-10 18:41:44 +0800215 }
216
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000217 private void setTimeOut(int timeout) {
218 timeOut.set(timeout);
ke han81a38b92017-03-10 18:41:44 +0800219 }
220
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000221 private void setTimeOut(Integer timeout) {
222 if (timeout == null) {
223 timeOut = null;
224 } else {
225 timeOut.set(timeout);
ke han81a38b92017-03-10 18:41:44 +0800226 }
227 }
228
Ilayda Ozdemir4c5947c2020-05-05 13:14:32 +0000229 private void createTimeOut(Integer timeout) {
230 timeOut = new AtomicInteger(timeout);
ke han81a38b92017-03-10 18:41:44 +0800231 }
232}